2 * Common HID report descriptor helpers
4 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
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
30 #define WIN32_NO_STATUS
35 #include "ddk/hidsdi.h"
37 #include "wine/debug.h"
40 #include "unix_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(hid
);
44 static BOOL
hid_report_descriptor_append(struct hid_report_descriptor
*desc
, const BYTE
*buffer
, SIZE_T size
)
46 BYTE
*tmp
= desc
->data
;
48 if (desc
->size
+ size
> desc
->max_size
)
50 desc
->max_size
= max(desc
->max_size
* 3 / 2, desc
->size
+ size
);
51 desc
->data
= realloc(tmp
, desc
->max_size
);
60 memcpy(desc
->data
+ desc
->size
, buffer
, size
);
65 #include "psh_hid_macros.h"
67 static BOOL
hid_report_descriptor_append_usage(struct hid_report_descriptor
*desc
, USAGE usage
)
69 const BYTE
template[] =
74 return hid_report_descriptor_append(desc
, template, sizeof(template));
77 static BOOL
hid_device_begin_collection(struct hid_report_descriptor
*desc
, const USAGE_AND_PAGE
*usage
, BYTE type
)
79 const BYTE
template[] =
81 USAGE_PAGE(2, usage
->UsagePage
),
82 USAGE(2, usage
->Usage
),
86 return hid_report_descriptor_append(desc
, template, sizeof(template));
89 static BOOL
hid_device_end_collection(struct hid_report_descriptor
*desc
)
91 static const BYTE
template[] =
96 return hid_report_descriptor_append(desc
, template, sizeof(template));
99 BOOL
hid_device_begin_report_descriptor(struct unix_device
*iface
, const USAGE_AND_PAGE
*device_usage
)
101 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
102 memset(desc
, 0, sizeof(*desc
));
103 return hid_device_begin_collection(desc
, device_usage
, Application
);
106 BOOL
hid_device_end_report_descriptor(struct unix_device
*iface
)
108 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
109 return hid_device_end_collection(desc
);
112 BOOL
hid_device_begin_input_report(struct unix_device
*iface
, const USAGE_AND_PAGE
*physical_usage
)
114 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
115 struct hid_device_state
*state
= &iface
->hid_device_state
;
116 const BYTE report_id
= ++desc
->next_report_id
[HidP_Input
];
117 const BYTE
template[] =
119 REPORT_ID(1, report_id
),
122 if (state
->report_len
)
124 ERR("input report already created\n");
128 state
->id
= report_id
;
129 state
->bit_size
+= 8;
131 if (!hid_device_begin_collection(desc
, physical_usage
, Physical
))
134 return hid_report_descriptor_append(desc
, template, sizeof(template));
137 BOOL
hid_device_end_input_report(struct unix_device
*iface
)
139 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
140 struct hid_device_state
*state
= &iface
->hid_device_state
;
142 state
->report_len
= (state
->bit_size
+ 7) / 8;
143 if (!(state
->report_buf
= calloc(1, state
->report_len
))) return FALSE
;
144 if (!(state
->last_report_buf
= calloc(1, state
->report_len
))) return FALSE
;
146 state
->report_buf
[0] = state
->id
;
147 state
->last_report_buf
[0] = state
->id
;
148 return hid_device_end_collection(desc
);
151 static BOOL
hid_device_add_button_count(struct unix_device
*iface
, BYTE count
)
153 USHORT offset
= iface
->hid_device_state
.bit_size
/ 8;
155 if ((iface
->hid_device_state
.bit_size
% 8) && !iface
->hid_device_state
.button_count
)
156 ERR("buttons should start byte aligned, missing padding!\n");
157 else if (iface
->hid_device_state
.bit_size
+ count
> 0x80000)
158 ERR("report size overflow, too many elements!\n");
161 if (!iface
->hid_device_state
.button_count
) iface
->hid_device_state
.button_start
= offset
;
162 iface
->hid_device_state
.button_count
+= count
;
163 iface
->hid_device_state
.bit_size
+= count
;
170 BOOL
hid_device_add_buttons(struct unix_device
*iface
, USAGE usage_page
, USAGE usage_min
, USAGE usage_max
)
172 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
173 const USHORT count
= usage_max
- usage_min
+ 1;
174 const BYTE
template[] =
176 USAGE_PAGE(2, usage_page
),
177 USAGE_MINIMUM(2, usage_min
),
178 USAGE_MAXIMUM(2, usage_max
),
179 LOGICAL_MINIMUM(1, 0),
180 LOGICAL_MAXIMUM(1, 1),
181 REPORT_COUNT(2, count
),
183 INPUT(1, Data
|Var
|Abs
),
185 const BYTE template_pad
[] =
187 REPORT_COUNT(1, 8 - (count
% 8)),
189 INPUT(1, Cnst
|Var
|Abs
),
192 if (!hid_device_add_button_count(iface
, usage_max
- usage_min
+ 1))
195 if (!hid_report_descriptor_append(desc
, template, sizeof(template)))
198 if ((count
% 8) && !hid_report_descriptor_append(desc
, template_pad
, sizeof(template_pad
)))
204 static BOOL
hid_device_add_hatswitch_count(struct unix_device
*iface
, BYTE count
)
206 USHORT offset
= iface
->hid_device_state
.bit_size
/ 8;
208 if (iface
->hid_device_state
.button_count
)
209 ERR("hatswitches should be added before buttons!\n");
210 else if ((iface
->hid_device_state
.bit_size
% 8))
211 ERR("hatswitches should be byte aligned, missing padding!\n");
212 else if (iface
->hid_device_state
.bit_size
+ 8 * count
> 0x80000)
213 ERR("report size overflow, too many elements!\n");
216 if (!iface
->hid_device_state
.hatswitch_count
) iface
->hid_device_state
.hatswitch_start
= offset
;
217 iface
->hid_device_state
.hatswitch_count
+= count
;
218 iface
->hid_device_state
.bit_size
+= 8 * count
;
225 BOOL
hid_device_add_hatswitch(struct unix_device
*iface
, INT count
)
227 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
228 const BYTE
template[] =
230 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
231 USAGE(1, HID_USAGE_GENERIC_HATSWITCH
),
232 LOGICAL_MINIMUM(1, 1),
233 LOGICAL_MAXIMUM(1, 8),
235 REPORT_COUNT(4, count
),
236 UNIT(1, 0x0e /* none */),
237 INPUT(1, Data
|Var
|Abs
|Null
),
240 if (!hid_device_add_hatswitch_count(iface
, count
))
243 return hid_report_descriptor_append(desc
, template, sizeof(template));
246 static BOOL
hid_device_add_axis_count(struct unix_device
*iface
, BOOL rel
, BYTE count
,
247 USAGE usage_page
, const USAGE
*usages
)
249 struct hid_device_state
*state
= &iface
->hid_device_state
;
250 USHORT i
, offset
= state
->bit_size
/ 8;
252 if (!rel
&& state
->rel_axis_count
)
253 ERR("absolute axes should be added before relative axes!\n");
254 else if (state
->button_count
|| state
->hatswitch_count
)
255 ERR("axes should be added before buttons or hatswitches!\n");
256 else if ((state
->bit_size
% 8))
257 ERR("axes should be byte aligned, missing padding!\n");
258 else if (state
->bit_size
+ 32 * count
> 0x80000)
259 ERR("report size overflow, too many elements!\n");
262 if (!state
->rel_axis_count
) state
->rel_axis_start
= offset
;
263 state
->rel_axis_count
+= count
;
264 state
->bit_size
+= 32 * count
;
269 if (state
->abs_axis_count
+ count
> ARRAY_SIZE(state
->abs_axis_usages
))
271 ERR("absolute axis usage overflow, too many elements!\n");
274 for (i
= 0; i
< count
; ++i
)
276 state
->abs_axis_usages
[state
->abs_axis_count
+ i
].UsagePage
= usage_page
;
277 state
->abs_axis_usages
[state
->abs_axis_count
+ i
].Usage
= usages
[i
];
280 if (!state
->abs_axis_count
) state
->abs_axis_start
= offset
;
281 state
->abs_axis_count
+= count
;
282 state
->bit_size
+= 32 * count
;
289 BOOL
hid_device_add_axes(struct unix_device
*iface
, BYTE count
, USAGE usage_page
,
290 const USAGE
*usages
, BOOL rel
, LONG min
, LONG max
)
292 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
293 const BYTE template_begin
[] =
295 USAGE_PAGE(1, usage_page
),
296 COLLECTION(1, Physical
),
298 const BYTE template_end
[] =
302 const BYTE
template[] =
304 LOGICAL_MINIMUM(4, min
),
305 LOGICAL_MAXIMUM(4, max
),
307 REPORT_COUNT(1, count
),
308 INPUT(1, Data
|Var
|(rel
? Rel
: Abs
)),
312 if (!hid_device_add_axis_count(iface
, rel
, count
, usage_page
, usages
))
315 if (!hid_report_descriptor_append(desc
, template_begin
, sizeof(template_begin
)))
318 for (i
= 0; i
< count
; i
++)
320 if (!hid_report_descriptor_append_usage(desc
, usages
[i
]))
324 if (!hid_report_descriptor_append(desc
, template, sizeof(template)))
327 if (!hid_report_descriptor_append(desc
, template_end
, sizeof(template_end
)))
333 #include "pshpack1.h"
334 struct hid_haptics_intensity
336 UINT16 rumble_intensity
;
337 UINT16 buzz_intensity
;
338 UINT16 left_intensity
;
339 UINT16 right_intensity
;
343 BOOL
hid_device_add_haptics(struct unix_device
*iface
)
345 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
346 const BYTE haptics_features_report
= ++desc
->next_report_id
[HidP_Feature
];
347 const BYTE haptics_intensity_report
= ++desc
->next_report_id
[HidP_Output
];
348 const BYTE haptics_template
[] =
350 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS
),
351 USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER
),
352 COLLECTION(1, Logical
),
353 REPORT_ID(1, haptics_features_report
),
355 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST
),
356 COLLECTION(1, NamedArray
),
357 /* ordinal 1 and 2 are reserved for implicit waveforms */
358 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<<16)|3),
361 FEATURE(1, Data
|Var
|Abs
|Null
),
364 USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST
),
365 COLLECTION(1, NamedArray
),
366 /* ordinal 1 and 2 are reserved for implicit waveforms */
367 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<<16)|3),
370 FEATURE(1, Data
|Var
|Abs
|Null
),
373 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME
),
374 UNIT(2, 0x1001), /* seconds */
375 UNIT_EXPONENT(1, -3), /* 10^-3 */
376 LOGICAL_MINIMUM(4, 0x00000000),
377 LOGICAL_MAXIMUM(4, 0x7fffffff),
380 FEATURE(1, Data
|Var
|Abs
),
381 /* reset global items */
382 UNIT(1, 0), /* None */
385 REPORT_ID(1, haptics_intensity_report
),
386 USAGE(1, HID_USAGE_HAPTICS_INTENSITY
),
387 LOGICAL_MINIMUM(4, 0x00000000),
388 LOGICAL_MAXIMUM(4, 0x0000ffff),
391 OUTPUT(1, Data
|Var
|Abs
),
394 const BYTE trigger_template_begin
[] =
396 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC
),
397 COLLECTION(1, Physical
),
399 const BYTE trigger_template_end
[] =
404 iface
->hid_haptics
.features_report
= haptics_features_report
;
405 iface
->hid_haptics
.intensity_report
= haptics_intensity_report
;
406 iface
->hid_haptics
.features
.rumble
.waveform
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
407 iface
->hid_haptics
.features
.rumble
.duration
= 0;
408 iface
->hid_haptics
.features
.rumble
.cutoff_time_ms
= 1000;
409 iface
->hid_haptics
.features
.buzz
.waveform
= HID_USAGE_HAPTICS_WAVEFORM_BUZZ
;
410 iface
->hid_haptics
.features
.buzz
.duration
= 0;
411 iface
->hid_haptics
.features
.buzz
.cutoff_time_ms
= 1000;
412 iface
->hid_haptics
.features
.left
.waveform
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
413 iface
->hid_haptics
.features
.left
.duration
= 0;
414 iface
->hid_haptics
.features
.left
.cutoff_time_ms
= 1000;
415 iface
->hid_haptics
.features
.right
.waveform
= HID_USAGE_HAPTICS_WAVEFORM_RUMBLE
;
416 iface
->hid_haptics
.features
.right
.duration
= 0;
417 iface
->hid_haptics
.features
.right
.cutoff_time_ms
= 1000;
419 if (!hid_report_descriptor_append(desc
, haptics_template
, sizeof(haptics_template
)))
421 if (!hid_report_descriptor_append(desc
, haptics_template
, sizeof(haptics_template
)))
424 if (!hid_report_descriptor_append_usage(desc
, HID_USAGE_GENERIC_Z
))
426 if (!hid_report_descriptor_append(desc
, trigger_template_begin
, sizeof(trigger_template_begin
)))
428 if (!hid_report_descriptor_append(desc
, haptics_template
, sizeof(haptics_template
)))
430 if (!hid_report_descriptor_append(desc
, trigger_template_end
, sizeof(trigger_template_end
)))
433 if (!hid_report_descriptor_append_usage(desc
, HID_USAGE_GENERIC_RZ
))
435 if (!hid_report_descriptor_append(desc
, trigger_template_begin
, sizeof(trigger_template_begin
)))
437 if (!hid_report_descriptor_append(desc
, haptics_template
, sizeof(haptics_template
)))
439 if (!hid_report_descriptor_append(desc
, trigger_template_end
, sizeof(trigger_template_end
)))
445 #include "pshpack1.h"
446 struct pid_device_control
451 static const USAGE pid_device_control_usages
[] =
453 0, /* HID nary collection indexes start at 1 */
454 PID_USAGE_DC_ENABLE_ACTUATORS
,
455 PID_USAGE_DC_DISABLE_ACTUATORS
,
456 PID_USAGE_DC_STOP_ALL_EFFECTS
,
457 PID_USAGE_DC_DEVICE_RESET
,
458 PID_USAGE_DC_DEVICE_PAUSE
,
459 PID_USAGE_DC_DEVICE_CONTINUE
,
462 struct pid_device_gain
467 struct pid_effect_control
474 static const USAGE pid_effect_control_usages
[] =
476 0, /* HID nary collection indexes start at 1 */
477 PID_USAGE_OP_EFFECT_START
,
478 PID_USAGE_OP_EFFECT_START_SOLO
,
479 PID_USAGE_OP_EFFECT_STOP
,
482 struct pid_effect_update
487 UINT16 trigger_repeat_interval
;
488 UINT16 sample_period
;
496 struct pid_set_periodic
505 struct pid_set_envelope
514 struct pid_set_condition
517 BYTE condition_index
;
518 INT16 center_point_offset
;
519 INT16 positive_coefficient
;
520 INT16 negative_coefficient
;
521 UINT16 positive_saturation
;
522 UINT16 negative_saturation
;
526 struct pid_set_constant_force
532 struct pid_set_ramp_force
539 struct pid_effect_state
546 static BOOL
hid_descriptor_add_set_periodic(struct unix_device
*iface
)
548 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
549 const BYTE report_id
= ++desc
->next_report_id
[HidP_Output
];
550 const BYTE
template[] =
552 /* Periodic Report Definition */
553 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT
),
554 COLLECTION(1, Logical
),
555 REPORT_ID(1, report_id
),
557 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
558 LOGICAL_MINIMUM(1, 0),
559 LOGICAL_MAXIMUM(1, 0x7f),
562 OUTPUT(1, Data
|Var
|Abs
),
564 USAGE(1, PID_USAGE_MAGNITUDE
),
565 LOGICAL_MINIMUM(1, 0),
566 LOGICAL_MAXIMUM(2, 0x7fff),
567 PHYSICAL_MINIMUM(1, 0),
568 PHYSICAL_MAXIMUM(2, 10000),
571 OUTPUT(1, Data
|Var
|Abs
),
572 PHYSICAL_MINIMUM(1, 0),
573 PHYSICAL_MAXIMUM(1, 0),
575 USAGE(1, PID_USAGE_OFFSET
),
576 LOGICAL_MINIMUM(2, 0x8000),
577 LOGICAL_MAXIMUM(2, 0x7fff),
578 PHYSICAL_MINIMUM(2, -10000),
579 PHYSICAL_MAXIMUM(2, +10000),
582 OUTPUT(1, Data
|Var
|Abs
),
583 PHYSICAL_MINIMUM(1, 0),
584 PHYSICAL_MAXIMUM(1, 0),
586 USAGE(1, PID_USAGE_PHASE
),
587 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
588 UNIT_EXPONENT(1, -2),
589 LOGICAL_MINIMUM(1, 0),
590 LOGICAL_MAXIMUM(4, 36000),
593 OUTPUT(1, Data
|Var
|Abs
),
595 USAGE(1, PID_USAGE_PERIOD
),
596 UNIT(2, 0x1003), /* Eng Lin:Time */
597 UNIT_EXPONENT(1, -3), /* 10^-3 */
598 LOGICAL_MINIMUM(1, 0),
599 LOGICAL_MAXIMUM(2, 0x7fff),
602 OUTPUT(1, Data
|Var
|Abs
),
605 UNIT(1, 0), /* None */
609 iface
->hid_physical
.set_periodic_report
= report_id
;
610 return hid_report_descriptor_append(desc
, template, sizeof(template));
613 static BOOL
hid_descriptor_add_set_envelope(struct unix_device
*iface
)
615 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
616 const BYTE report_id
= ++desc
->next_report_id
[HidP_Output
];
617 const BYTE
template[] =
619 /* Envelope Report Definition */
620 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT
),
621 COLLECTION(1, Logical
),
622 REPORT_ID(1, report_id
),
624 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
625 LOGICAL_MINIMUM(1, 0),
626 LOGICAL_MAXIMUM(1, 0x7f),
629 OUTPUT(1, Data
|Var
|Abs
),
631 USAGE(1, PID_USAGE_ATTACK_LEVEL
),
632 USAGE(1, PID_USAGE_FADE_LEVEL
),
633 LOGICAL_MINIMUM(1, 0),
634 LOGICAL_MAXIMUM(2, 0x7fff),
635 PHYSICAL_MINIMUM(1, 0),
636 PHYSICAL_MAXIMUM(2, 10000),
639 OUTPUT(1, Data
|Var
|Abs
),
640 PHYSICAL_MINIMUM(1, 0),
641 PHYSICAL_MAXIMUM(1, 0),
643 USAGE(1, PID_USAGE_ATTACK_TIME
),
644 USAGE(1, PID_USAGE_FADE_TIME
),
645 UNIT(2, 0x1003), /* Eng Lin:Time */
646 UNIT_EXPONENT(1, -3),
647 LOGICAL_MINIMUM(1, 0),
648 LOGICAL_MAXIMUM(2, 0x7fff),
651 OUTPUT(1, Data
|Var
|Abs
),
652 PHYSICAL_MAXIMUM(1, 0),
658 iface
->hid_physical
.set_envelope_report
= report_id
;
659 return hid_report_descriptor_append(desc
, template, sizeof(template));
662 static BOOL
hid_descriptor_add_set_condition(struct unix_device
*iface
)
664 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
665 const BYTE report_id
= ++desc
->next_report_id
[HidP_Output
];
666 const BYTE
template[] =
668 /* Condition Report Definition */
669 USAGE(1, PID_USAGE_SET_CONDITION_REPORT
),
670 COLLECTION(1, Logical
),
671 REPORT_ID(1, report_id
),
673 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
674 LOGICAL_MINIMUM(1, 0),
675 LOGICAL_MAXIMUM(1, 0x7f),
678 OUTPUT(1, Data
|Var
|Abs
),
680 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET
),
681 LOGICAL_MINIMUM(1, 0x00),
682 LOGICAL_MAXIMUM(1, 0x01),
685 OUTPUT(1, Data
|Var
|Abs
),
687 USAGE(1, PID_USAGE_CP_OFFSET
),
688 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT
),
689 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT
),
690 LOGICAL_MINIMUM(2, 0x8000),
691 LOGICAL_MAXIMUM(2, 0x7fff),
692 PHYSICAL_MINIMUM(2, -10000),
693 PHYSICAL_MAXIMUM(2, +10000),
696 OUTPUT(1, Data
|Var
|Abs
),
697 PHYSICAL_MINIMUM(1, 0),
698 PHYSICAL_MAXIMUM(1, 0),
700 USAGE(1, PID_USAGE_POSITIVE_SATURATION
),
701 USAGE(1, PID_USAGE_NEGATIVE_SATURATION
),
702 USAGE(1, PID_USAGE_DEAD_BAND
),
703 LOGICAL_MINIMUM(1, 0),
704 LOGICAL_MAXIMUM(4, 0xffff),
705 PHYSICAL_MINIMUM(1, 0),
706 PHYSICAL_MAXIMUM(2, +10000),
709 OUTPUT(1, Data
|Var
|Abs
),
710 PHYSICAL_MINIMUM(1, 0),
711 PHYSICAL_MAXIMUM(1, 0),
715 iface
->hid_physical
.set_condition_report
= report_id
;
716 return hid_report_descriptor_append(desc
, template, sizeof(template));
719 static BOOL
hid_descriptor_add_set_constant_force(struct unix_device
*iface
)
721 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
722 const BYTE report_id
= ++desc
->next_report_id
[HidP_Output
];
723 const BYTE
template[] =
725 /* Constant Force Report Definition */
726 USAGE(1, PID_USAGE_SET_CONSTANT_FORCE_REPORT
),
727 COLLECTION(1, Logical
),
728 REPORT_ID(1, report_id
),
730 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
731 LOGICAL_MINIMUM(1, 0),
732 LOGICAL_MAXIMUM(1, 0x7f),
735 OUTPUT(1, Data
|Var
|Abs
),
737 USAGE(1, PID_USAGE_MAGNITUDE
),
738 LOGICAL_MINIMUM(2, 0x8000),
739 LOGICAL_MAXIMUM(2, 0x7fff),
740 PHYSICAL_MINIMUM(2, -10000),
741 PHYSICAL_MAXIMUM(2, +10000),
744 OUTPUT(1, Data
|Var
|Abs
),
745 PHYSICAL_MINIMUM(1, 0),
746 PHYSICAL_MAXIMUM(1, 0),
750 iface
->hid_physical
.set_constant_force_report
= report_id
;
751 return hid_report_descriptor_append(desc
, template, sizeof(template));
754 static BOOL
hid_descriptor_add_set_ramp_force(struct unix_device
*iface
)
756 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
757 const BYTE report_id
= ++desc
->next_report_id
[HidP_Output
];
758 const BYTE
template[] =
760 /* Ramp Force Report Definition */
761 USAGE(1, PID_USAGE_SET_RAMP_FORCE_REPORT
),
762 COLLECTION(1, Logical
),
763 REPORT_ID(1, report_id
),
765 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
766 LOGICAL_MINIMUM(1, 0),
767 LOGICAL_MAXIMUM(1, 0x7f),
770 OUTPUT(1, Data
|Var
|Abs
),
772 USAGE(1, PID_USAGE_RAMP_START
),
773 USAGE(1, PID_USAGE_RAMP_END
),
774 LOGICAL_MINIMUM(2, 0x8000),
775 LOGICAL_MAXIMUM(2, 0x7fff),
776 PHYSICAL_MINIMUM(2, -10000),
777 PHYSICAL_MAXIMUM(2, +10000),
780 OUTPUT(1, Data
|Var
|Abs
),
781 PHYSICAL_MINIMUM(1, 0),
782 PHYSICAL_MAXIMUM(1, 0),
786 iface
->hid_physical
.set_ramp_force_report
= report_id
;
787 return hid_report_descriptor_append(desc
, template, sizeof(template));
790 BOOL
hid_device_add_physical(struct unix_device
*iface
, USAGE
*usages
, USHORT count
)
792 struct hid_report_descriptor
*desc
= &iface
->hid_report_descriptor
;
793 const BYTE device_control_report
= ++desc
->next_report_id
[HidP_Output
];
794 struct hid_device_state
*state
= &iface
->hid_device_state
;
795 const BYTE device_control_header
[] =
797 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
798 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT
),
799 COLLECTION(1, Logical
),
800 REPORT_ID(1, device_control_report
),
802 USAGE(1, PID_USAGE_DEVICE_CONTROL
),
803 COLLECTION(1, Logical
),
805 const BYTE device_control_footer
[] =
807 LOGICAL_MINIMUM(1, 1),
808 LOGICAL_MAXIMUM(1, 6),
811 OUTPUT(1, Data
|Ary
|Abs
),
816 const BYTE device_gain_report
= ++desc
->next_report_id
[HidP_Output
];
817 const BYTE device_gain
[] =
819 USAGE_PAGE(1, HID_USAGE_PAGE_PID
),
820 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT
),
821 COLLECTION(1, Logical
),
822 REPORT_ID(1, device_gain_report
),
824 USAGE(1, PID_USAGE_DEVICE_GAIN
),
825 LOGICAL_MINIMUM(1, 0),
826 LOGICAL_MAXIMUM(1, 100),
827 PHYSICAL_MINIMUM(1, 0),
828 PHYSICAL_MAXIMUM(2, 10000),
831 OUTPUT(1, Data
|Var
|Abs
),
832 PHYSICAL_MINIMUM(1, 0),
833 PHYSICAL_MAXIMUM(1, 0),
837 const BYTE effect_control_report
= ++desc
->next_report_id
[HidP_Output
];
838 const BYTE effect_control_header
[] =
840 /* Control effect state */
841 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT
),
842 COLLECTION(1, Logical
),
843 REPORT_ID(1, effect_control_report
),
845 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
846 LOGICAL_MINIMUM(1, 0),
847 LOGICAL_MAXIMUM(1, 0x7f),
850 OUTPUT(1, Data
|Var
|Abs
),
852 USAGE(1, PID_USAGE_EFFECT_OPERATION
),
853 COLLECTION(1, Logical
),
855 const BYTE effect_control_footer
[] =
857 LOGICAL_MINIMUM(1, 1),
858 LOGICAL_MAXIMUM(1, 3),
861 OUTPUT(1, Data
|Ary
|Abs
),
864 USAGE(1, PID_USAGE_LOOP_COUNT
),
865 LOGICAL_MINIMUM(1, 0),
866 LOGICAL_MAXIMUM(2, 0x00ff),
869 OUTPUT(1, Data
|Var
|Abs
),
873 const BYTE effect_update_report
= ++desc
->next_report_id
[HidP_Output
];
874 const BYTE effect_update_header
[] =
876 /* Set effect properties */
877 USAGE(1, PID_USAGE_SET_EFFECT_REPORT
),
878 COLLECTION(1, Logical
),
879 REPORT_ID(1, effect_update_report
),
881 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
882 LOGICAL_MINIMUM(1, 0),
883 LOGICAL_MAXIMUM(1, 0x7f),
886 OUTPUT(1, Data
|Var
|Abs
),
888 USAGE(1, PID_USAGE_EFFECT_TYPE
),
889 COLLECTION(1, Logical
),
891 const BYTE effect_update_footer
[] =
893 LOGICAL_MINIMUM(1, 1),
894 LOGICAL_MAXIMUM(1, count
),
896 OUTPUT(1, Data
|Ary
|Abs
),
899 USAGE(1, PID_USAGE_DURATION
),
900 USAGE(1, PID_USAGE_TRIGGER_REPEAT_INTERVAL
),
901 USAGE(1, PID_USAGE_SAMPLE_PERIOD
),
902 USAGE(1, PID_USAGE_START_DELAY
),
903 UNIT(2, 0x1003), /* Eng Lin:Time */
904 UNIT_EXPONENT(1, -3), /* 10^-3 */
905 LOGICAL_MINIMUM(1, 0),
906 LOGICAL_MAXIMUM(2, 0x7fff),
909 OUTPUT(1, Data
|Var
|Abs
),
911 UNIT(1, 0), /* None */
913 USAGE(1, PID_USAGE_GAIN
),
914 LOGICAL_MINIMUM(1, 0),
915 LOGICAL_MAXIMUM(1, 100),
918 OUTPUT(1, Data
|Var
|Abs
|Null
),
920 USAGE(1, PID_USAGE_TRIGGER_BUTTON
),
921 LOGICAL_MINIMUM(1, 0),
922 LOGICAL_MAXIMUM(2, state
->button_count
),
925 OUTPUT(1, Data
|Var
|Abs
|Null
),
927 USAGE(1, PID_USAGE_AXES_ENABLE
),
928 COLLECTION(1, Logical
),
929 USAGE(4, (state
->abs_axis_usages
[0].UsagePage
<<16)|state
->abs_axis_usages
[0].Usage
),
930 USAGE(4, (state
->abs_axis_usages
[1].UsagePage
<<16)|state
->abs_axis_usages
[1].Usage
),
931 LOGICAL_MINIMUM(1, 0),
932 LOGICAL_MAXIMUM(1, 1),
935 OUTPUT(1, Data
|Var
|Abs
),
937 USAGE(1, PID_USAGE_DIRECTION_ENABLE
),
939 OUTPUT(1, Data
|Var
|Abs
),
941 OUTPUT(1, Cnst
|Var
|Abs
), /* 5-bit pad */
943 USAGE(1, PID_USAGE_DIRECTION
),
944 COLLECTION(1, Logical
),
945 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<<16)|1),
946 USAGE(4, (HID_USAGE_PAGE_ORDINAL
<<16)|2),
947 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
948 UNIT_EXPONENT(1, -2),
949 LOGICAL_MINIMUM(1, 0),
950 LOGICAL_MAXIMUM(4, 36000),
953 OUTPUT(1, Data
|Var
|Abs
),
956 UNIT(1, 0), /* None */
960 const BYTE effect_state_report
= ++desc
->next_report_id
[HidP_Input
];
961 const BYTE effect_state_template
[] =
963 /* Report effect state */
964 USAGE(1, PID_USAGE_STATE_REPORT
),
965 COLLECTION(1, Logical
),
966 REPORT_ID(1, effect_state_report
),
968 USAGE(1, PID_USAGE_DEVICE_PAUSED
),
969 USAGE(1, PID_USAGE_ACTUATORS_ENABLED
),
970 USAGE(1, PID_USAGE_EFFECT_PLAYING
),
971 LOGICAL_MINIMUM(1, 0),
972 LOGICAL_MAXIMUM(1, 1),
975 INPUT(1, Data
|Var
|Abs
),
977 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX
),
978 LOGICAL_MINIMUM(1, 0),
979 LOGICAL_MAXIMUM(1, 0x7f),
982 INPUT(1, Data
|Var
|Abs
),
985 struct hid_effect_state
*effect_state
= &iface
->hid_physical
.effect_state
;
986 BOOL periodic
= FALSE
;
987 BOOL envelope
= FALSE
;
988 BOOL condition
= FALSE
;
989 BOOL constant_force
= FALSE
;
990 BOOL ramp_force
= FALSE
;
993 if (!hid_report_descriptor_append(desc
, device_control_header
, sizeof(device_control_header
)))
995 for (i
= 1; i
< ARRAY_SIZE(pid_device_control_usages
); ++i
)
997 if (!hid_report_descriptor_append_usage(desc
, pid_device_control_usages
[i
]))
1000 if (!hid_report_descriptor_append(desc
, device_control_footer
, sizeof(device_control_footer
)))
1003 if (!hid_report_descriptor_append(desc
, device_gain
, sizeof(device_gain
)))
1006 if (!hid_report_descriptor_append(desc
, effect_control_header
, sizeof(effect_control_header
)))
1008 for (i
= 1; i
< ARRAY_SIZE(pid_effect_control_usages
); ++i
)
1010 if (!hid_report_descriptor_append_usage(desc
, pid_effect_control_usages
[i
]))
1013 if (!hid_report_descriptor_append(desc
, effect_control_footer
, sizeof(effect_control_footer
)))
1016 if (!hid_report_descriptor_append(desc
, effect_update_header
, sizeof(effect_update_header
)))
1018 for (i
= 0; i
< count
; ++i
)
1020 if (!hid_report_descriptor_append_usage(desc
, usages
[i
]))
1023 if (!hid_report_descriptor_append(desc
, effect_update_footer
, sizeof(effect_update_footer
)))
1026 for (i
= 0; i
< count
; ++i
)
1028 if (usages
[i
] == PID_USAGE_ET_SINE
||
1029 usages
[i
] == PID_USAGE_ET_SQUARE
||
1030 usages
[i
] == PID_USAGE_ET_TRIANGLE
||
1031 usages
[i
] == PID_USAGE_ET_SAWTOOTH_UP
||
1032 usages
[i
] == PID_USAGE_ET_SAWTOOTH_DOWN
)
1033 periodic
= envelope
= TRUE
;
1034 if (usages
[i
] == PID_USAGE_ET_SPRING
||
1035 usages
[i
] == PID_USAGE_ET_DAMPER
||
1036 usages
[i
] == PID_USAGE_ET_INERTIA
||
1037 usages
[i
] == PID_USAGE_ET_FRICTION
)
1039 if (usages
[i
] == PID_USAGE_ET_CONSTANT_FORCE
)
1040 envelope
= constant_force
= TRUE
;
1041 if (usages
[i
] == PID_USAGE_ET_RAMP
)
1042 envelope
= ramp_force
= TRUE
;
1045 if (periodic
&& !hid_descriptor_add_set_periodic(iface
))
1047 if (envelope
&& !hid_descriptor_add_set_envelope(iface
))
1049 if (condition
&& !hid_descriptor_add_set_condition(iface
))
1051 if (constant_force
&& !hid_descriptor_add_set_constant_force(iface
))
1053 if (ramp_force
&& !hid_descriptor_add_set_ramp_force(iface
))
1056 if (!hid_report_descriptor_append(desc
, effect_state_template
, sizeof(effect_state_template
)))
1059 /* HID nary collection indexes start at 1 */
1060 memcpy(iface
->hid_physical
.effect_types
+ 1, usages
, count
* sizeof(*usages
));
1062 iface
->hid_physical
.device_control_report
= device_control_report
;
1063 iface
->hid_physical
.device_gain_report
= device_gain_report
;
1064 iface
->hid_physical
.effect_control_report
= effect_control_report
;
1065 iface
->hid_physical
.effect_update_report
= effect_update_report
;
1067 effect_state
->id
= effect_state_report
;
1068 effect_state
->report_len
= sizeof(struct pid_effect_state
) + 1;
1069 if (!(effect_state
->report_buf
= calloc(1, effect_state
->report_len
))) return FALSE
;
1070 effect_state
->report_buf
[0] = effect_state
->id
;
1075 #include "pop_hid_macros.h"
1077 static void hid_device_destroy(struct unix_device
*iface
)
1079 iface
->hid_vtbl
->destroy(iface
);
1080 free(iface
->hid_report_descriptor
.data
);
1081 free(iface
->hid_device_state
.report_buf
);
1082 free(iface
->hid_device_state
.last_report_buf
);
1085 static NTSTATUS
hid_device_start(struct unix_device
*iface
)
1087 return iface
->hid_vtbl
->start(iface
);
1090 static void hid_device_stop(struct unix_device
*iface
)
1092 iface
->hid_vtbl
->stop(iface
);
1095 static NTSTATUS
hid_device_get_report_descriptor(struct unix_device
*iface
, BYTE
*buffer
, UINT length
, UINT
*out_length
)
1097 *out_length
= iface
->hid_report_descriptor
.size
;
1098 if (length
< iface
->hid_report_descriptor
.size
) return STATUS_BUFFER_TOO_SMALL
;
1100 memcpy(buffer
, iface
->hid_report_descriptor
.data
, iface
->hid_report_descriptor
.size
);
1101 return STATUS_SUCCESS
;
1104 static void hid_device_set_output_report(struct unix_device
*iface
, HID_XFER_PACKET
*packet
, IO_STATUS_BLOCK
*io
)
1106 struct hid_physical
*physical
= &iface
->hid_physical
;
1107 struct hid_haptics
*haptics
= &iface
->hid_haptics
;
1109 if (packet
->reportId
== haptics
->intensity_report
)
1111 struct hid_haptics_intensity
*report
= (struct hid_haptics_intensity
*)(packet
->reportBuffer
+ 1);
1114 io
->Information
= sizeof(*report
) + 1;
1115 assert(packet
->reportBufferLen
== io
->Information
);
1117 if (!report
->rumble_intensity
&& !report
->buzz_intensity
&& !report
->left_intensity
&& !report
->right_intensity
)
1118 io
->Status
= iface
->hid_vtbl
->haptics_stop(iface
);
1121 duration_ms
= min(haptics
->features
.rumble
.cutoff_time_ms
, haptics
->features
.buzz
.cutoff_time_ms
);
1122 duration_ms
= min(duration_ms
, haptics
->features
.left
.cutoff_time_ms
);
1123 duration_ms
= min(duration_ms
, haptics
->features
.right
.cutoff_time_ms
);
1124 io
->Status
= iface
->hid_vtbl
->haptics_start(iface
, duration_ms
, report
->rumble_intensity
, report
->buzz_intensity
,
1125 report
->left_intensity
, report
->right_intensity
);
1128 else if (packet
->reportId
== physical
->device_control_report
)
1130 struct pid_device_control
*report
= (struct pid_device_control
*)(packet
->reportBuffer
+ 1);
1133 io
->Information
= sizeof(*report
) + 1;
1134 if (packet
->reportBufferLen
< io
->Information
)
1135 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1136 else if (report
->control_index
>= ARRAY_SIZE(pid_device_control_usages
))
1137 io
->Status
= STATUS_INVALID_PARAMETER
;
1138 else if (!(control
= pid_device_control_usages
[report
->control_index
]))
1139 io
->Status
= STATUS_INVALID_PARAMETER
;
1142 io
->Status
= iface
->hid_vtbl
->physical_device_control(iface
, control
);
1143 if (control
== PID_USAGE_DC_DEVICE_RESET
&& io
->Status
== STATUS_SUCCESS
)
1144 memset(physical
->effect_params
, 0, sizeof(physical
->effect_params
));
1147 else if (packet
->reportId
== physical
->device_gain_report
)
1149 struct pid_device_gain
*report
= (struct pid_device_gain
*)(packet
->reportBuffer
+ 1);
1151 io
->Information
= sizeof(*report
) + 1;
1152 if (packet
->reportBufferLen
< io
->Information
)
1153 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1155 io
->Status
= iface
->hid_vtbl
->physical_device_set_gain(iface
, report
->value
);
1157 else if (packet
->reportId
== physical
->effect_control_report
)
1159 struct pid_effect_control
*report
= (struct pid_effect_control
*)(packet
->reportBuffer
+ 1);
1162 io
->Information
= sizeof(*report
) + 1;
1163 if (packet
->reportBufferLen
< io
->Information
)
1164 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1165 else if (report
->control_index
>= ARRAY_SIZE(pid_effect_control_usages
))
1166 io
->Status
= STATUS_INVALID_PARAMETER
;
1167 else if (!(control
= pid_effect_control_usages
[report
->control_index
]))
1168 io
->Status
= STATUS_INVALID_PARAMETER
;
1170 io
->Status
= iface
->hid_vtbl
->physical_effect_control(iface
, report
->index
, control
, report
->iterations
);
1172 else if (packet
->reportId
== physical
->effect_update_report
)
1174 struct pid_effect_update
*report
= (struct pid_effect_update
*)(packet
->reportBuffer
+ 1);
1175 struct effect_params
*params
= iface
->hid_physical
.effect_params
+ report
->index
;
1178 io
->Information
= sizeof(*report
) + 1;
1179 if (packet
->reportBufferLen
< io
->Information
)
1180 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1181 else if (report
->type_index
>= ARRAY_SIZE(iface
->hid_physical
.effect_types
))
1182 io
->Status
= STATUS_INVALID_PARAMETER
;
1183 else if (!(effect_type
= iface
->hid_physical
.effect_types
[report
->type_index
]))
1184 io
->Status
= STATUS_INVALID_PARAMETER
;
1187 params
->effect_type
= effect_type
;
1188 params
->duration
= report
->duration
;
1189 params
->trigger_repeat_interval
= report
->trigger_repeat_interval
;
1190 params
->sample_period
= report
->sample_period
;
1191 params
->start_delay
= report
->start_delay
;
1192 params
->gain_percent
= report
->gain_percent
;
1193 params
->trigger_button
= report
->trigger_button
== 0xff ? 0 : report
->trigger_button
;
1194 params
->axis_enabled
[0] = (report
->enable_bits
& 1) != 0;
1195 params
->axis_enabled
[1] = (report
->enable_bits
& 2) != 0;
1196 params
->direction_enabled
= (report
->enable_bits
& 4) != 0;
1197 params
->direction
[0] = report
->direction
[0];
1198 params
->direction
[1] = report
->direction
[1];
1200 io
->Status
= iface
->hid_vtbl
->physical_effect_update(iface
, report
->index
, params
);
1203 else if (packet
->reportId
== physical
->set_periodic_report
)
1205 struct pid_set_periodic
*report
= (struct pid_set_periodic
*)(packet
->reportBuffer
+ 1);
1206 struct effect_params
*params
= iface
->hid_physical
.effect_params
+ report
->index
;
1208 io
->Information
= sizeof(*report
) + 1;
1209 if (packet
->reportBufferLen
< io
->Information
)
1210 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1213 params
->periodic
.magnitude
= report
->magnitude
;
1214 params
->periodic
.offset
= report
->offset
;
1215 params
->periodic
.phase
= report
->phase
;
1216 params
->periodic
.period
= report
->period
;
1218 io
->Status
= iface
->hid_vtbl
->physical_effect_update(iface
, report
->index
, params
);
1221 else if (packet
->reportId
== physical
->set_envelope_report
)
1223 struct pid_set_envelope
*report
= (struct pid_set_envelope
*)(packet
->reportBuffer
+ 1);
1224 struct effect_params
*params
= iface
->hid_physical
.effect_params
+ report
->index
;
1226 io
->Information
= sizeof(*report
) + 1;
1227 if (packet
->reportBufferLen
< io
->Information
)
1228 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1231 params
->envelope
.attack_level
= report
->attack_level
;
1232 params
->envelope
.fade_level
= report
->fade_level
;
1233 params
->envelope
.attack_time
= report
->attack_time
;
1234 params
->envelope
.fade_time
= report
->fade_time
;
1236 io
->Status
= iface
->hid_vtbl
->physical_effect_update(iface
, report
->index
, params
);
1239 else if (packet
->reportId
== physical
->set_condition_report
)
1241 struct pid_set_condition
*report
= (struct pid_set_condition
*)(packet
->reportBuffer
+ 1);
1242 struct effect_params
*params
= iface
->hid_physical
.effect_params
+ report
->index
;
1243 struct effect_condition
*condition
;
1246 io
->Information
= sizeof(*report
) + 1;
1247 if (packet
->reportBufferLen
< io
->Information
)
1248 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1249 else if ((index
= report
->condition_index
) >= ARRAY_SIZE(params
->condition
))
1250 io
->Status
= STATUS_INVALID_PARAMETER
;
1253 if (params
->condition_count
<= index
) params
->condition_count
= index
+ 1;
1254 condition
= params
->condition
+ index
;
1255 condition
->center_point_offset
= report
->center_point_offset
;
1256 condition
->positive_coefficient
= report
->positive_coefficient
;
1257 condition
->negative_coefficient
= report
->negative_coefficient
;
1258 condition
->positive_saturation
= report
->positive_saturation
;
1259 condition
->negative_saturation
= report
->negative_saturation
;
1260 condition
->dead_band
= report
->dead_band
;
1262 io
->Status
= iface
->hid_vtbl
->physical_effect_update(iface
, report
->index
, params
);
1265 else if (packet
->reportId
== physical
->set_constant_force_report
)
1267 struct pid_set_constant_force
*report
= (struct pid_set_constant_force
*)(packet
->reportBuffer
+ 1);
1268 struct effect_params
*params
= iface
->hid_physical
.effect_params
+ report
->index
;
1270 io
->Information
= sizeof(*report
) + 1;
1271 if (packet
->reportBufferLen
< io
->Information
)
1272 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1275 params
->constant_force
.magnitude
= report
->magnitude
;
1277 io
->Status
= iface
->hid_vtbl
->physical_effect_update(iface
, report
->index
, params
);
1280 else if (packet
->reportId
== physical
->set_ramp_force_report
)
1282 struct pid_set_ramp_force
*report
= (struct pid_set_ramp_force
*)(packet
->reportBuffer
+ 1);
1283 struct effect_params
*params
= iface
->hid_physical
.effect_params
+ report
->index
;
1285 io
->Information
= sizeof(*report
) + 1;
1286 if (packet
->reportBufferLen
< io
->Information
)
1287 io
->Status
= STATUS_BUFFER_TOO_SMALL
;
1290 params
->ramp_force
.ramp_start
= report
->ramp_start
;
1291 params
->ramp_force
.ramp_end
= report
->ramp_end
;
1293 io
->Status
= iface
->hid_vtbl
->physical_effect_update(iface
, report
->index
, params
);
1298 io
->Information
= 0;
1299 io
->Status
= STATUS_NOT_IMPLEMENTED
;
1303 static void hid_device_get_feature_report(struct unix_device
*iface
, HID_XFER_PACKET
*packet
, IO_STATUS_BLOCK
*io
)
1305 struct hid_haptics
*haptics
= &iface
->hid_haptics
;
1307 if (packet
->reportId
== haptics
->features_report
)
1309 struct hid_haptics_features
*features
= (struct hid_haptics_features
*)(packet
->reportBuffer
+ 1);
1311 io
->Information
= sizeof(*features
) + 1;
1312 assert(packet
->reportBufferLen
== io
->Information
);
1314 *features
= haptics
->features
;
1315 io
->Status
= STATUS_SUCCESS
;
1319 io
->Information
= 0;
1320 io
->Status
= STATUS_NOT_IMPLEMENTED
;
1324 static void hid_device_set_feature_report(struct unix_device
*iface
, HID_XFER_PACKET
*packet
, IO_STATUS_BLOCK
*io
)
1326 struct hid_haptics
*haptics
= &iface
->hid_haptics
;
1328 if (packet
->reportId
== haptics
->features_report
)
1330 struct hid_haptics_features
*features
= (struct hid_haptics_features
*)(packet
->reportBuffer
+ 1);
1332 io
->Information
= sizeof(*features
) + 1;
1333 assert(packet
->reportBufferLen
== io
->Information
);
1335 haptics
->features
.rumble
.cutoff_time_ms
= features
->rumble
.cutoff_time_ms
;
1336 haptics
->features
.buzz
.cutoff_time_ms
= features
->buzz
.cutoff_time_ms
;
1337 haptics
->features
.left
.cutoff_time_ms
= features
->left
.cutoff_time_ms
;
1338 haptics
->features
.right
.cutoff_time_ms
= features
->right
.cutoff_time_ms
;
1339 io
->Status
= STATUS_SUCCESS
;
1343 io
->Information
= 0;
1344 io
->Status
= STATUS_NOT_IMPLEMENTED
;
1348 static const struct raw_device_vtbl raw_device_vtbl
=
1353 hid_device_get_report_descriptor
,
1354 hid_device_set_output_report
,
1355 hid_device_get_feature_report
,
1356 hid_device_set_feature_report
,
1359 void *hid_device_create(const struct hid_device_vtbl
*vtbl
, SIZE_T size
)
1361 struct unix_device
*impl
;
1363 if (!(impl
= raw_device_create(&raw_device_vtbl
, size
))) return NULL
;
1364 impl
->hid_vtbl
= vtbl
;
1369 #ifdef WORDS_BIGENDIAN
1370 # define LE_ULONG(x) RtlUlongByteSwap((ULONG)(x))
1372 # define LE_ULONG(x) ((ULONG)(x))
1375 BOOL
hid_device_set_abs_axis(struct unix_device
*iface
, ULONG index
, LONG value
)
1377 struct hid_device_state
*state
= &iface
->hid_device_state
;
1378 ULONG offset
= state
->abs_axis_start
+ index
* 4;
1379 if (index
> state
->abs_axis_count
) return FALSE
;
1380 *(ULONG
*)(state
->report_buf
+ offset
) = LE_ULONG(value
);
1384 BOOL
hid_device_set_rel_axis(struct unix_device
*iface
, ULONG index
, LONG value
)
1386 struct hid_device_state
*state
= &iface
->hid_device_state
;
1387 ULONG offset
= state
->rel_axis_start
+ index
* 4;
1388 if (index
> state
->rel_axis_count
) return FALSE
;
1389 *(ULONG
*)(state
->report_buf
+ offset
) = LE_ULONG(value
);
1393 BOOL
hid_device_set_button(struct unix_device
*iface
, ULONG index
, BOOL is_set
)
1395 struct hid_device_state
*state
= &iface
->hid_device_state
;
1396 ULONG offset
= state
->button_start
+ (index
/ 8);
1397 BYTE mask
= (1 << (index
% 8));
1398 if (index
> state
->button_count
) return FALSE
;
1399 if (is_set
) state
->report_buf
[offset
] |= mask
;
1400 else state
->report_buf
[offset
] &= ~mask
;
1404 /* hatswitch x / y vs value:
1412 static void hatswitch_decompose(BYTE value
, LONG
*x
, LONG
*y
)
1415 if (value
== 8 || value
== 1 || value
== 2) *y
= -1;
1416 if (value
== 6 || value
== 5 || value
== 4) *y
= +1;
1417 if (value
== 8 || value
== 7 || value
== 6) *x
= -1;
1418 if (value
== 2 || value
== 3 || value
== 4) *x
= +1;
1421 static void hatswitch_compose(LONG x
, LONG y
, BYTE
*value
)
1423 if (x
== 0 && y
== 0) *value
= 0;
1424 else if (x
== 0 && y
< 0) *value
= 1;
1425 else if (x
> 0 && y
< 0) *value
= 2;
1426 else if (x
> 0 && y
== 0) *value
= 3;
1427 else if (x
> 0 && y
> 0) *value
= 4;
1428 else if (x
== 0 && y
> 0) *value
= 5;
1429 else if (x
< 0 && y
> 0) *value
= 6;
1430 else if (x
< 0 && y
== 0) *value
= 7;
1431 else if (x
< 0 && y
< 0) *value
= 8;
1434 BOOL
hid_device_set_hatswitch_x(struct unix_device
*iface
, ULONG index
, LONG new_x
)
1436 struct hid_device_state
*state
= &iface
->hid_device_state
;
1437 ULONG offset
= state
->hatswitch_start
+ index
;
1439 if (index
> state
->hatswitch_count
) return FALSE
;
1440 hatswitch_decompose(state
->report_buf
[offset
], &x
, &y
);
1441 hatswitch_compose(new_x
, y
, &state
->report_buf
[offset
]);
1445 BOOL
hid_device_set_hatswitch_y(struct unix_device
*iface
, ULONG index
, LONG new_y
)
1447 struct hid_device_state
*state
= &iface
->hid_device_state
;
1448 ULONG offset
= state
->hatswitch_start
+ index
;
1450 if (index
> state
->hatswitch_count
) return FALSE
;
1451 hatswitch_decompose(state
->report_buf
[offset
], &x
, &y
);
1452 hatswitch_compose(x
, new_y
, &state
->report_buf
[offset
]);
1456 BOOL
hid_device_move_hatswitch(struct unix_device
*iface
, ULONG index
, LONG x
, LONG y
)
1458 struct hid_device_state
*state
= &iface
->hid_device_state
;
1459 ULONG offset
= state
->hatswitch_start
+ index
;
1461 if (index
> state
->hatswitch_count
) return FALSE
;
1462 hatswitch_decompose(state
->report_buf
[offset
], &old_x
, &old_y
);
1463 hatswitch_compose(old_x
+ x
, old_y
+ y
, &state
->report_buf
[offset
]);
1467 BOOL
hid_device_sync_report(struct unix_device
*iface
)
1471 if (!(dropped
= iface
->hid_device_state
.dropped
))
1472 memcpy(iface
->hid_device_state
.last_report_buf
, iface
->hid_device_state
.report_buf
,
1473 iface
->hid_device_state
.report_len
);
1475 memcpy(iface
->hid_device_state
.report_buf
, iface
->hid_device_state
.last_report_buf
,
1476 iface
->hid_device_state
.report_len
);
1477 iface
->hid_device_state
.dropped
= FALSE
;
1482 void hid_device_drop_report(struct unix_device
*iface
)
1484 iface
->hid_device_state
.dropped
= TRUE
;
1487 void hid_device_set_effect_state(struct unix_device
*iface
, BYTE index
, BYTE flags
)
1489 struct hid_effect_state
*state
= &iface
->hid_physical
.effect_state
;
1490 struct pid_effect_state
*report
= (struct pid_effect_state
*)(state
->report_buf
+ 1);
1491 report
->index
= index
;
1492 report
->flags
= flags
;