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
275 USAGE usages_page
[256];
276 USAGE usages_min
[256];
277 USAGE usages_max
[256];
280 struct hid_value_caps items
;
282 struct hid_value_caps
*stack
;
285 DWORD collection_idx
;
287 struct hid_value_caps
*collections
;
288 DWORD collections_size
;
290 struct hid_value_caps
*values
[3];
291 ULONG values_size
[3];
293 ULONG bit_size
[3][256];
294 USHORT
*byte_size
[3]; /* pointers to caps */
295 USHORT
*value_idx
[3]; /* pointers to caps */
296 USHORT
*data_idx
[3]; /* pointers to caps */
299 static BOOL
array_reserve( struct hid_value_caps
**array
, DWORD
*array_size
, DWORD index
)
301 if (index
< *array_size
) return TRUE
;
302 if ((*array_size
= *array_size
? (*array_size
* 3 / 2) : 32) <= index
) return FALSE
;
303 if (!(*array
= realloc( *array
, *array_size
* sizeof(**array
) ))) return FALSE
;
307 static void copy_global_items( struct hid_value_caps
*dst
, const struct hid_value_caps
*src
)
309 dst
->usage_page
= src
->usage_page
;
310 dst
->logical_min
= src
->logical_min
;
311 dst
->logical_max
= src
->logical_max
;
312 dst
->physical_min
= src
->physical_min
;
313 dst
->physical_max
= src
->physical_max
;
314 dst
->units_exp
= src
->units_exp
;
315 dst
->units
= src
->units
;
316 dst
->bit_size
= src
->bit_size
;
317 dst
->report_id
= src
->report_id
;
318 dst
->report_count
= src
->report_count
;
321 static void copy_collection_items( struct hid_value_caps
*dst
, const struct hid_value_caps
*src
)
323 dst
->link_collection
= src
->link_collection
;
324 dst
->link_usage_page
= src
->link_usage_page
;
325 dst
->link_usage
= src
->link_usage
;
328 static void reset_local_items( struct hid_parser_state
*state
)
330 struct hid_value_caps tmp
;
331 copy_global_items( &tmp
, &state
->items
);
332 copy_collection_items( &tmp
, &state
->items
);
333 memset( &state
->items
, 0, sizeof(state
->items
) );
334 copy_global_items( &state
->items
, &tmp
);
335 copy_collection_items( &state
->items
, &tmp
);
336 memset( &state
->usages_page
, 0, sizeof(state
->usages_page
) );
337 memset( &state
->usages_min
, 0, sizeof(state
->usages_min
) );
338 memset( &state
->usages_max
, 0, sizeof(state
->usages_max
) );
339 state
->usages_size
= 0;
342 static BOOL
parse_global_push( struct hid_parser_state
*state
)
344 if (!array_reserve( &state
->stack
, &state
->stack_size
, state
->global_idx
))
346 ERR( "HID parser stack overflow!\n" );
350 copy_global_items( state
->stack
+ state
->global_idx
, &state
->items
);
355 static BOOL
parse_global_pop( struct hid_parser_state
*state
)
357 if (!state
->global_idx
)
359 ERR( "HID parser global stack underflow!\n" );
364 copy_global_items( &state
->items
, state
->stack
+ state
->global_idx
);
368 static BOOL
parse_local_usage( struct hid_parser_state
*state
, USAGE usage_page
, USAGE usage
)
370 if (!usage_page
) usage_page
= state
->items
.usage_page
;
371 if (state
->items
.is_range
) state
->usages_size
= 0;
372 state
->usages_page
[state
->usages_size
] = usage_page
;
373 state
->usages_min
[state
->usages_size
] = usage
;
374 state
->usages_max
[state
->usages_size
] = usage
;
375 state
->items
.usage_min
= usage
;
376 state
->items
.usage_max
= usage
;
377 state
->items
.is_range
= FALSE
;
378 if (state
->usages_size
++ == 255) ERR( "HID parser usages stack overflow!\n" );
379 return state
->usages_size
<= 255;
382 static void parse_local_usage_min( struct hid_parser_state
*state
, USAGE usage_page
, USAGE usage
)
384 if (!usage_page
) usage_page
= state
->items
.usage_page
;
385 if (!state
->items
.is_range
) state
->usages_max
[0] = 0;
386 state
->usages_page
[0] = usage_page
;
387 state
->usages_min
[0] = usage
;
388 state
->items
.usage_min
= usage
;
389 state
->items
.is_range
= TRUE
;
390 state
->usages_size
= 1;
393 static void parse_local_usage_max( struct hid_parser_state
*state
, USAGE usage_page
, USAGE usage
)
395 if (!usage_page
) usage_page
= state
->items
.usage_page
;
396 if (!state
->items
.is_range
) state
->usages_min
[0] = 0;
397 state
->usages_page
[0] = usage_page
;
398 state
->usages_max
[0] = usage
;
399 state
->items
.usage_max
= usage
;
400 state
->items
.is_range
= TRUE
;
401 state
->usages_size
= 1;
404 static BOOL
parse_new_collection( struct hid_parser_state
*state
)
406 if (!array_reserve( &state
->stack
, &state
->stack_size
, state
->collection_idx
))
408 ERR( "HID parser stack overflow!\n" );
412 if (!array_reserve( &state
->collections
, &state
->collections_size
, state
->caps
.NumberLinkCollectionNodes
))
414 ERR( "HID parser collections overflow!\n" );
418 copy_collection_items( state
->stack
+ state
->collection_idx
, &state
->items
);
419 state
->collection_idx
++;
421 state
->items
.usage_min
= state
->usages_min
[0];
422 state
->items
.usage_max
= state
->usages_max
[0];
424 state
->collections
[state
->caps
.NumberLinkCollectionNodes
] = state
->items
;
425 state
->items
.link_collection
= state
->caps
.NumberLinkCollectionNodes
;
426 state
->items
.link_usage_page
= state
->items
.usage_page
;
427 state
->items
.link_usage
= state
->items
.usage_min
;
428 if (!state
->caps
.NumberLinkCollectionNodes
)
430 state
->caps
.UsagePage
= state
->items
.usage_page
;
431 state
->caps
.Usage
= state
->items
.usage_min
;
433 state
->caps
.NumberLinkCollectionNodes
++;
435 reset_local_items( state
);
439 static BOOL
parse_end_collection( struct hid_parser_state
*state
)
441 if (!state
->collection_idx
)
443 ERR( "HID parser collection stack underflow!\n" );
447 state
->collection_idx
--;
448 copy_collection_items( &state
->items
, state
->stack
+ state
->collection_idx
);
449 reset_local_items( state
);
453 static BOOL
parse_new_value_caps( struct hid_parser_state
*state
, HIDP_REPORT_TYPE type
, struct collection
*collection
)
455 struct hid_value_caps
*value
;
456 USAGE usage_page
= state
->items
.usage_page
;
457 DWORD usages_size
= max(1, state
->usages_size
);
458 USHORT
*byte_size
= state
->byte_size
[type
];
459 USHORT
*value_idx
= state
->value_idx
[type
];
460 USHORT
*data_idx
= state
->data_idx
[type
];
461 ULONG
*bit_size
= &state
->bit_size
[type
][state
->items
.report_id
];
462 struct feature
*feature
;
465 for (j
= 0; j
< state
->items
.report_count
; j
++)
467 if (!(feature
= calloc( 1, sizeof(*feature
) ))) return -1;
468 list_add_tail( &collection
->features
, &feature
->entry
);
469 feature
->type
= type
;
470 feature
->isData
= ((state
->items
.bit_field
& INPUT_DATA_CONST
) == 0);
471 copy_hidp_value_caps( &feature
->caps
, &state
->items
);
472 if (j
< state
->usages_size
) feature
->caps
.NotRange
.Usage
= state
->usages_min
[j
];
473 feature
->caps
.ReportCount
= 1;
474 if (j
+ 1 >= state
->usages_size
)
476 feature
->caps
.ReportCount
+= state
->items
.report_count
- (j
+ 1);
481 if (!*bit_size
) *bit_size
= 8;
482 *bit_size
+= state
->items
.bit_size
* state
->items
.report_count
;
483 *byte_size
= max( *byte_size
, (*bit_size
+ 7) / 8 );
484 state
->items
.start_bit
= *bit_size
;
486 if (!state
->items
.report_count
)
488 reset_local_items( state
);
492 if (!array_reserve( &state
->values
[type
], &state
->values_size
[type
], *value_idx
+ usages_size
))
494 ERR( "HID parser values overflow!\n" );
497 value
= state
->values
[type
] + *value_idx
;
499 state
->items
.report_count
-= usages_size
- 1;
500 while (usages_size
--)
502 state
->items
.start_bit
-= state
->items
.report_count
* state
->items
.bit_size
;
503 state
->items
.usage_page
= state
->usages_page
[usages_size
];
504 state
->items
.usage_min
= state
->usages_min
[usages_size
];
505 state
->items
.usage_max
= state
->usages_max
[usages_size
];
506 state
->items
.data_index_min
= *data_idx
;
507 state
->items
.data_index_max
= *data_idx
+ state
->items
.usage_max
- state
->items
.usage_min
;
508 if (state
->items
.usage_max
|| state
->items
.usage_min
) *data_idx
= state
->items
.data_index_max
+ 1;
509 *value
++ = state
->items
;
511 state
->items
.report_count
= 1;
514 state
->items
.usage_page
= usage_page
;
515 reset_local_items( state
);
519 static void init_parser_state( struct hid_parser_state
*state
)
521 memset( state
, 0, sizeof(*state
) );
522 state
->byte_size
[HidP_Input
] = &state
->caps
.InputReportByteLength
;
523 state
->byte_size
[HidP_Output
] = &state
->caps
.OutputReportByteLength
;
524 state
->byte_size
[HidP_Feature
] = &state
->caps
.FeatureReportByteLength
;
526 state
->value_idx
[HidP_Input
] = &state
->caps
.NumberInputValueCaps
;
527 state
->value_idx
[HidP_Output
] = &state
->caps
.NumberOutputValueCaps
;
528 state
->value_idx
[HidP_Feature
] = &state
->caps
.NumberFeatureValueCaps
;
530 state
->data_idx
[HidP_Input
] = &state
->caps
.NumberInputDataIndices
;
531 state
->data_idx
[HidP_Output
] = &state
->caps
.NumberOutputDataIndices
;
532 state
->data_idx
[HidP_Feature
] = &state
->caps
.NumberFeatureDataIndices
;
535 static void free_parser_state( struct hid_parser_state
*state
)
537 if (state
->global_idx
) ERR( "%u unpopped device caps on the stack\n", state
->global_idx
);
538 if (state
->collection_idx
) ERR( "%u unpopped device collection on the stack\n", state
->collection_idx
);
539 free( state
->stack
);
540 free( state
->collections
);
541 free( state
->values
[HidP_Input
] );
542 free( state
->values
[HidP_Output
] );
543 free( state
->values
[HidP_Feature
] );
547 static void parse_collection(unsigned int bSize
, int itemVal
,
548 struct collection
*collection
)
552 collection
->type
= itemVal
;
554 if (itemVal
>= 0x07 && itemVal
<= 0x7F) {
555 ERR(" (Reserved 0x%x )\n", itemVal
);
557 else if (itemVal
>= 0x80 && itemVal
<= 0xFF) {
558 ERR(" (Vendor Defined 0x%x )\n", itemVal
);
563 static int parse_descriptor( BYTE
*descriptor
, unsigned int index
, unsigned int length
,
564 struct collection
*collection
, struct hid_parser_state
*state
)
570 for (i
= index
; i
< length
;)
572 BYTE item
= descriptor
[i
++];
573 int size
= item
& 0x03;
575 if (size
== 3) size
= 4;
576 if (length
- i
< size
)
578 ERR("Need %d bytes to read item value\n", size
);
582 if (size
== 0) signed_value
= value
= 0;
583 else if (size
== 1) signed_value
= (INT8
)(value
= *(UINT8
*)(descriptor
+ i
));
584 else if (size
== 2) signed_value
= (INT16
)(value
= *(UINT16
*)(descriptor
+ i
));
585 else if (size
== 4) signed_value
= (INT32
)(value
= *(UINT32
*)(descriptor
+ i
));
588 ERR("Unexpected item value size %d.\n", size
);
593 state
->items
.bit_field
= value
;
595 #define SHORT_ITEM(tag,type) (((tag)<<4)|((type)<<2))
596 switch (item
& SHORT_ITEM(0xf,0x3))
598 case SHORT_ITEM(TAG_MAIN_INPUT
, TAG_TYPE_MAIN
):
599 if (!parse_new_value_caps( state
, HidP_Input
, collection
)) return -1;
601 case SHORT_ITEM(TAG_MAIN_OUTPUT
, TAG_TYPE_MAIN
):
602 if (!parse_new_value_caps( state
, HidP_Output
, collection
)) return -1;
604 case SHORT_ITEM(TAG_MAIN_FEATURE
, TAG_TYPE_MAIN
):
605 if (!parse_new_value_caps( state
, HidP_Feature
, collection
)) return -1;
607 case SHORT_ITEM(TAG_MAIN_COLLECTION
, TAG_TYPE_MAIN
):
609 struct collection
*subcollection
;
610 if (!(subcollection
= calloc(1, sizeof(struct collection
)))) return -1;
611 list_add_tail(&collection
->collections
, &subcollection
->entry
);
612 subcollection
->parent
= collection
;
613 /* Only set our collection once...
614 We do not properly handle composite devices yet. */
615 list_init(&subcollection
->features
);
616 list_init(&subcollection
->collections
);
617 parse_collection(size
, value
, subcollection
);
618 if (!parse_new_collection( state
)) return -1;
620 if ((i
= parse_descriptor( descriptor
, i
, length
, subcollection
, state
)) < 0) return i
;
623 case SHORT_ITEM(TAG_MAIN_END_COLLECTION
, TAG_TYPE_MAIN
):
624 if (!parse_end_collection( state
)) return -1;
627 case SHORT_ITEM(TAG_GLOBAL_USAGE_PAGE
, TAG_TYPE_GLOBAL
):
628 state
->items
.usage_page
= value
;
630 case SHORT_ITEM(TAG_GLOBAL_LOGICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
631 state
->items
.logical_min
= signed_value
;
633 case SHORT_ITEM(TAG_GLOBAL_LOGICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
634 state
->items
.logical_max
= signed_value
;
636 case SHORT_ITEM(TAG_GLOBAL_PHYSICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
637 state
->items
.physical_min
= signed_value
;
639 case SHORT_ITEM(TAG_GLOBAL_PHYSICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
640 state
->items
.physical_max
= signed_value
;
642 case SHORT_ITEM(TAG_GLOBAL_UNIT_EXPONENT
, TAG_TYPE_GLOBAL
):
643 state
->items
.units_exp
= signed_value
;
645 case SHORT_ITEM(TAG_GLOBAL_UNIT
, TAG_TYPE_GLOBAL
):
646 state
->items
.units
= signed_value
;
648 case SHORT_ITEM(TAG_GLOBAL_REPORT_SIZE
, TAG_TYPE_GLOBAL
):
649 state
->items
.bit_size
= value
;
651 case SHORT_ITEM(TAG_GLOBAL_REPORT_ID
, TAG_TYPE_GLOBAL
):
652 state
->items
.report_id
= value
;
654 case SHORT_ITEM(TAG_GLOBAL_REPORT_COUNT
, TAG_TYPE_GLOBAL
):
655 state
->items
.report_count
= value
;
657 case SHORT_ITEM(TAG_GLOBAL_PUSH
, TAG_TYPE_GLOBAL
):
658 if (!parse_global_push( state
)) return -1;
660 case SHORT_ITEM(TAG_GLOBAL_POP
, TAG_TYPE_GLOBAL
):
661 if (!parse_global_pop( state
)) return -1;
664 case SHORT_ITEM(TAG_LOCAL_USAGE
, TAG_TYPE_LOCAL
):
665 if (!parse_local_usage( state
, value
>> 16, value
& 0xffff )) return -1;
667 case SHORT_ITEM(TAG_LOCAL_USAGE_MINIMUM
, TAG_TYPE_LOCAL
):
668 parse_local_usage_min( state
, value
>> 16, value
& 0xffff );
670 case SHORT_ITEM(TAG_LOCAL_USAGE_MAXIMUM
, TAG_TYPE_LOCAL
):
671 parse_local_usage_max( state
, value
>> 16, value
& 0xffff );
673 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_INDEX
, TAG_TYPE_LOCAL
):
674 state
->items
.designator_min
= state
->items
.designator_max
= value
;
675 state
->items
.is_designator_range
= FALSE
;
677 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_MINIMUM
, TAG_TYPE_LOCAL
):
678 state
->items
.designator_min
= value
;
679 state
->items
.is_designator_range
= TRUE
;
681 case SHORT_ITEM(TAG_LOCAL_DESIGNATOR_MAXIMUM
, TAG_TYPE_LOCAL
):
682 state
->items
.designator_max
= value
;
683 state
->items
.is_designator_range
= TRUE
;
685 case SHORT_ITEM(TAG_LOCAL_STRING_INDEX
, TAG_TYPE_LOCAL
):
686 state
->items
.string_min
= state
->items
.string_max
= value
;
687 state
->items
.is_string_range
= FALSE
;
689 case SHORT_ITEM(TAG_LOCAL_STRING_MINIMUM
, TAG_TYPE_LOCAL
):
690 state
->items
.string_min
= value
;
691 state
->items
.is_string_range
= TRUE
;
693 case SHORT_ITEM(TAG_LOCAL_STRING_MAXIMUM
, TAG_TYPE_LOCAL
):
694 state
->items
.string_max
= value
;
695 state
->items
.is_string_range
= TRUE
;
697 case SHORT_ITEM(TAG_LOCAL_DELIMITER
, TAG_TYPE_LOCAL
):
698 FIXME("delimiter %d not implemented!\n", value
);
702 FIXME("item type %x not implemented!\n", item
);
710 static void build_elements(WINE_HID_REPORT
*wine_report
, WINE_HID_ELEMENT
*elems
,
711 struct feature
* feature
, USHORT
*data_index
)
713 WINE_HID_ELEMENT
*wine_element
= elems
+ wine_report
->elementIdx
+ wine_report
->elementCount
;
716 if (!feature
->isData
)
718 wine_report
->bitSize
+= feature
->caps
.BitSize
* feature
->caps
.ReportCount
;
722 wine_element
->valueStartBit
= wine_report
->bitSize
;
724 wine_element
->bitCount
= (feature
->caps
.BitSize
* feature
->caps
.ReportCount
);
725 wine_report
->bitSize
+= wine_element
->bitCount
;
727 wine_element
->caps
= feature
->caps
;
729 if (wine_element
->caps
.IsRange
)
731 if (wine_element
->caps
.BitSize
== 1) index_count
= wine_element
->bitCount
- 1;
732 else index_count
= wine_element
->caps
.Range
.UsageMax
- wine_element
->caps
.Range
.UsageMin
;
733 wine_element
->caps
.Range
.DataIndexMin
= *data_index
;
734 wine_element
->caps
.Range
.DataIndexMax
= *data_index
+ index_count
;
735 *data_index
= *data_index
+ index_count
+ 1;
739 wine_element
->caps
.NotRange
.DataIndex
= *data_index
;
740 wine_element
->caps
.NotRange
.Reserved4
= *data_index
;
741 *data_index
= *data_index
+ 1;
744 wine_report
->elementCount
++;
747 static void count_elements(struct feature
* feature
, USHORT
*buttons
, USHORT
*values
)
749 if (!feature
->isData
)
752 if (feature
->caps
.BitSize
== 1)
762 int report_elem_count
[3][256];
765 BOOL report_created
[3][256];
768 static void create_preparse_ctx(const struct collection
*base
, struct preparse_ctx
*ctx
)
771 struct collection
*c
;
773 LIST_FOR_EACH_ENTRY(f
, &base
->features
, struct feature
, entry
)
776 ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
]++;
777 if (ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
] != 1)
779 ctx
->report_count
[f
->type
]++;
782 LIST_FOR_EACH_ENTRY(c
, &base
->collections
, struct collection
, entry
)
783 create_preparse_ctx(c
, ctx
);
786 static void preparse_collection(const struct collection
*root
, const struct collection
*base
,
787 WINE_HIDP_PREPARSED_DATA
*data
, struct preparse_ctx
*ctx
)
789 WINE_HID_ELEMENT
*elem
= HID_ELEMS(data
);
791 struct collection
*c
;
793 LIST_FOR_EACH_ENTRY(f
, &base
->features
, struct feature
, entry
)
795 WINE_HID_REPORT
*report
;
797 if (!ctx
->report_created
[f
->type
][f
->caps
.ReportID
])
799 ctx
->report_created
[f
->type
][f
->caps
.ReportID
] = TRUE
;
800 data
->reportIdx
[f
->type
][f
->caps
.ReportID
] = data
->reportCount
[f
->type
]++;
801 if (f
->type
> 0) data
->reportIdx
[f
->type
][f
->caps
.ReportID
] += ctx
->report_count
[0];
802 if (f
->type
> 1) data
->reportIdx
[f
->type
][f
->caps
.ReportID
] += ctx
->report_count
[1];
804 report
= &data
->reports
[data
->reportIdx
[f
->type
][f
->caps
.ReportID
]];
805 report
->reportID
= f
->caps
.ReportID
;
806 /* Room for the reportID */
808 report
->elementIdx
= ctx
->elem_alloc
;
809 ctx
->elem_alloc
+= ctx
->report_elem_count
[f
->type
][f
->caps
.ReportID
];
812 report
= &data
->reports
[data
->reportIdx
[f
->type
][f
->caps
.ReportID
]];
816 build_elements(report
, elem
, f
, &data
->caps
.NumberInputDataIndices
);
817 count_elements(f
, &data
->caps
.NumberInputButtonCaps
, &data
->caps
.NumberInputValueCaps
);
820 build_elements(report
, elem
, f
, &data
->caps
.NumberOutputDataIndices
);
821 count_elements(f
, &data
->caps
.NumberOutputButtonCaps
, &data
->caps
.NumberOutputValueCaps
);
824 build_elements(report
, elem
, f
, &data
->caps
.NumberFeatureDataIndices
);
825 count_elements(f
, &data
->caps
.NumberFeatureButtonCaps
, &data
->caps
.NumberFeatureValueCaps
);
830 LIST_FOR_EACH_ENTRY(c
, &base
->collections
, struct collection
, entry
)
831 preparse_collection(root
, c
, data
, ctx
);
834 static WINE_HIDP_PREPARSED_DATA
*build_preparsed_data( struct collection
*base_collection
,
835 struct hid_parser_state
*state
)
837 WINE_HIDP_PREPARSED_DATA
*data
;
838 struct hid_value_caps
*caps
;
839 unsigned int report_count
;
841 DWORD i
, button
, filler
, caps_len
, caps_off
;
843 struct preparse_ctx ctx
;
844 unsigned int element_off
;
846 memset(&ctx
, 0, sizeof(ctx
));
847 create_preparse_ctx(base_collection
, &ctx
);
849 report_count
= ctx
.report_count
[HidP_Input
] + ctx
.report_count
[HidP_Output
]
850 + ctx
.report_count
[HidP_Feature
];
851 element_off
= FIELD_OFFSET(WINE_HIDP_PREPARSED_DATA
, reports
[report_count
]);
852 size
= element_off
+ (ctx
.elem_count
* sizeof(WINE_HID_ELEMENT
));
854 caps_len
= state
->caps
.NumberInputValueCaps
+ state
->caps
.NumberOutputValueCaps
+
855 state
->caps
.NumberFeatureValueCaps
+ state
->caps
.NumberLinkCollectionNodes
;
857 size
+= caps_len
* sizeof(*caps
);
859 if (!(data
= calloc(1, size
))) return NULL
;
860 data
->magic
= HID_MAGIC
;
862 data
->caps
= state
->caps
;
863 data
->new_caps
= state
->caps
;
864 data
->elementOffset
= element_off
;
866 data
->value_caps_offset
= caps_off
;
867 data
->value_caps_count
[HidP_Input
] = state
->caps
.NumberInputValueCaps
;
868 data
->value_caps_count
[HidP_Output
] = state
->caps
.NumberOutputValueCaps
;
869 data
->value_caps_count
[HidP_Feature
] = state
->caps
.NumberFeatureValueCaps
;
871 data
->caps
.NumberInputValueCaps
= data
->caps
.NumberInputButtonCaps
= data
->caps
.NumberInputDataIndices
= 0;
872 data
->caps
.NumberOutputValueCaps
= data
->caps
.NumberOutputButtonCaps
= data
->caps
.NumberOutputDataIndices
= 0;
873 data
->caps
.NumberFeatureValueCaps
= data
->caps
.NumberFeatureButtonCaps
= data
->caps
.NumberFeatureDataIndices
= 0;
874 preparse_collection(base_collection
, base_collection
, data
, &ctx
);
876 /* fixup value vs button vs filler counts */
878 caps
= HID_INPUT_VALUE_CAPS( data
);
879 memcpy( caps
, state
->values
[0], data
->new_caps
.NumberInputValueCaps
* sizeof(*caps
) );
880 for (i
= 0, button
= 0, filler
= 0; i
< data
->new_caps
.NumberInputValueCaps
; ++i
)
882 if (!caps
[i
].usage_min
&& !caps
[i
].usage_max
) filler
++;
883 else if (HID_VALUE_CAPS_IS_BUTTON( caps
+ i
)) button
++;
885 data
->new_caps
.NumberInputButtonCaps
= button
;
886 data
->new_caps
.NumberInputValueCaps
-= filler
+ button
;
888 caps
= HID_OUTPUT_VALUE_CAPS( data
);
889 memcpy( caps
, state
->values
[1], data
->new_caps
.NumberOutputValueCaps
* sizeof(*caps
) );
890 for (i
= 0, button
= 0, filler
= 0; i
< data
->new_caps
.NumberOutputValueCaps
; ++i
)
892 if (!caps
[i
].usage_min
&& !caps
[i
].usage_max
) filler
++;
893 else if (HID_VALUE_CAPS_IS_BUTTON( caps
+ i
)) button
++;
895 caps
+= data
->new_caps
.NumberOutputValueCaps
;
896 data
->new_caps
.NumberOutputButtonCaps
= button
;
897 data
->new_caps
.NumberOutputValueCaps
-= filler
+ button
;
899 caps
= HID_FEATURE_VALUE_CAPS( data
);
900 memcpy( caps
, state
->values
[2], data
->new_caps
.NumberFeatureValueCaps
* sizeof(*caps
) );
901 for (i
= 0, button
= 0, filler
= 0; i
< data
->new_caps
.NumberFeatureValueCaps
; ++i
)
903 if (!caps
[i
].usage_min
&& !caps
[i
].usage_max
) filler
++;
904 else if (HID_VALUE_CAPS_IS_BUTTON( caps
+ i
)) button
++;
906 caps
+= data
->new_caps
.NumberFeatureValueCaps
;
907 data
->new_caps
.NumberFeatureButtonCaps
= button
;
908 data
->new_caps
.NumberFeatureValueCaps
-= filler
+ button
;
910 caps
= HID_COLLECTION_VALUE_CAPS( data
);
911 memcpy( caps
, state
->collections
, data
->new_caps
.NumberLinkCollectionNodes
* sizeof(*caps
) );
916 static void free_collection(struct collection
*collection
)
918 struct feature
*fentry
, *fnext
;
919 struct collection
*centry
, *cnext
;
920 LIST_FOR_EACH_ENTRY_SAFE(centry
, cnext
, &collection
->collections
, struct collection
, entry
)
922 list_remove(¢ry
->entry
);
923 free_collection(centry
);
925 LIST_FOR_EACH_ENTRY_SAFE(fentry
, fnext
, &collection
->features
, struct feature
, entry
)
927 list_remove(&fentry
->entry
);
933 WINE_HIDP_PREPARSED_DATA
* ParseDescriptor(BYTE
*descriptor
, unsigned int length
)
935 WINE_HIDP_PREPARSED_DATA
*data
= NULL
;
936 struct hid_parser_state
*state
;
937 struct collection
*base
;
942 TRACE("descriptor %p, length %u:\n", descriptor
, length
);
943 for (i
= 0; i
< length
;)
946 do { TRACE(" %02x", descriptor
[i
]); } while (++i
% 16 && i
< length
);
951 if (!(state
= calloc( 1, sizeof(*state
) ))) return NULL
;
952 if (!(base
= calloc( 1, sizeof(*base
) )))
957 list_init(&base
->features
);
958 list_init(&base
->collections
);
959 init_parser_state( state
);
961 if (parse_descriptor( descriptor
, 0, length
, base
, state
) < 0)
963 free_collection(base
);
964 free_parser_state( state
);
968 debug_collection(base
);
970 if ((data
= build_preparsed_data( base
, state
)))
971 debug_print_preparsed(data
);
972 free_collection(base
);
974 free_parser_state( state
);