msdasql: Implement IColumnsRowset GetAvailableColumns.
[wine.git] / dlls / winebus.sys / hid.c
blobc5543e081aef159980f061417b6bd960f9ead358
1 /*
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
21 #if 0
22 #pragma makedep unix
23 #endif
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <assert.h>
29 #include "ntstatus.h"
30 #define WIN32_NO_STATUS
31 #include "winternl.h"
32 #include "winioctl.h"
33 #include "hidusage.h"
34 #include "ddk/wdm.h"
35 #include "ddk/hidsdi.h"
37 #include "wine/debug.h"
38 #include "wine/hid.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);
54 if (!desc->data)
56 free(tmp);
57 return FALSE;
60 memcpy(desc->data + desc->size, buffer, size);
61 desc->size += size;
62 return TRUE;
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[] =
71 USAGE(2, usage),
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),
83 COLLECTION(1, type),
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[] =
93 END_COLLECTION,
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");
125 return FALSE;
128 state->id = report_id;
129 state->bit_size += 8;
131 if (!hid_device_begin_collection(desc, physical_usage, Physical))
132 return FALSE;
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");
159 else
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;
164 return TRUE;
167 return FALSE;
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),
182 REPORT_SIZE(1, 1),
183 INPUT(1, Data|Var|Abs),
185 const BYTE template_pad[] =
187 REPORT_COUNT(1, 8 - (count % 8)),
188 REPORT_SIZE(1, 1),
189 INPUT(1, Cnst|Var|Abs),
192 if (!hid_device_add_button_count(iface, usage_max - usage_min + 1))
193 return FALSE;
195 if (!hid_report_descriptor_append(desc, template, sizeof(template)))
196 return FALSE;
198 if ((count % 8) && !hid_report_descriptor_append(desc, template_pad, sizeof(template_pad)))
199 return FALSE;
201 return TRUE;
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");
214 else
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;
219 return TRUE;
222 return FALSE;
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),
234 REPORT_SIZE(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))
241 return FALSE;
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");
260 else if (rel)
262 if (!state->rel_axis_count) state->rel_axis_start = offset;
263 state->rel_axis_count += count;
264 state->bit_size += 32 * count;
265 return TRUE;
267 else
269 if (state->abs_axis_count + count > ARRAY_SIZE(state->abs_axis_usages))
271 ERR("absolute axis usage overflow, too many elements!\n");
272 return FALSE;
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;
283 return TRUE;
286 return FALSE;
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[] =
300 END_COLLECTION,
302 const BYTE template[] =
304 LOGICAL_MINIMUM(4, min),
305 LOGICAL_MAXIMUM(4, max),
306 REPORT_SIZE(1, 32),
307 REPORT_COUNT(1, count),
308 INPUT(1, Data|Var|(rel ? Rel : Abs)),
310 int i;
312 if (!hid_device_add_axis_count(iface, rel, count, usage_page, usages))
313 return FALSE;
315 if (!hid_report_descriptor_append(desc, template_begin, sizeof(template_begin)))
316 return FALSE;
318 for (i = 0; i < count; i++)
320 if (!hid_report_descriptor_append_usage(desc, usages[i]))
321 return FALSE;
324 if (!hid_report_descriptor_append(desc, template, sizeof(template)))
325 return FALSE;
327 if (!hid_report_descriptor_append(desc, template_end, sizeof(template_end)))
328 return FALSE;
330 return TRUE;
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;
341 #include "poppack.h"
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),
359 REPORT_SIZE(1, 16),
360 REPORT_COUNT(1, 1),
361 FEATURE(1, Data|Var|Abs|Null),
362 END_COLLECTION,
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),
368 REPORT_SIZE(1, 16),
369 REPORT_COUNT(1, 1),
370 FEATURE(1, Data|Var|Abs|Null),
371 END_COLLECTION,
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),
378 REPORT_SIZE(1, 32),
379 REPORT_COUNT(1, 1),
380 FEATURE(1, Data|Var|Abs),
381 /* reset global items */
382 UNIT(1, 0), /* None */
383 UNIT_EXPONENT(1, 0),
385 REPORT_ID(1, haptics_intensity_report),
386 USAGE(1, HID_USAGE_HAPTICS_INTENSITY),
387 LOGICAL_MINIMUM(4, 0x00000000),
388 LOGICAL_MAXIMUM(4, 0x0000ffff),
389 REPORT_SIZE(1, 16),
390 REPORT_COUNT(1, 1),
391 OUTPUT(1, Data|Var|Abs),
392 END_COLLECTION,
394 const BYTE trigger_template_begin[] =
396 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
397 COLLECTION(1, Physical),
399 const BYTE trigger_template_end[] =
401 END_COLLECTION,
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)))
420 return FALSE;
421 if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
422 return FALSE;
424 if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_Z))
425 return FALSE;
426 if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin)))
427 return FALSE;
428 if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
429 return FALSE;
430 if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end)))
431 return FALSE;
433 if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_RZ))
434 return FALSE;
435 if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin)))
436 return FALSE;
437 if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
438 return FALSE;
439 if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end)))
440 return FALSE;
442 return TRUE;
445 #include "pshpack1.h"
446 struct pid_device_control
448 BYTE control_index;
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
464 BYTE value;
467 struct pid_effect_control
469 BYTE index;
470 BYTE control_index;
471 BYTE iterations;
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
484 BYTE index;
485 BYTE type_index;
486 UINT16 duration;
487 UINT16 trigger_repeat_interval;
488 UINT16 sample_period;
489 UINT16 start_delay;
490 BYTE gain_percent;
491 BYTE trigger_button;
492 BYTE enable_bits;
493 UINT16 direction[2];
496 struct pid_set_periodic
498 BYTE index;
499 UINT16 magnitude;
500 INT16 offset;
501 UINT16 phase;
502 UINT16 period;
505 struct pid_set_envelope
507 BYTE index;
508 UINT16 attack_level;
509 UINT16 fade_level;
510 UINT16 attack_time;
511 UINT16 fade_time;
514 struct pid_set_condition
516 BYTE index;
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;
523 UINT16 dead_band;
526 struct pid_set_constant_force
528 BYTE index;
529 INT16 magnitude;
532 struct pid_set_ramp_force
534 BYTE index;
535 INT16 ramp_start;
536 INT16 ramp_end;
539 struct pid_effect_state
541 BYTE flags;
542 BYTE index;
544 #include "poppack.h"
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),
560 REPORT_SIZE(1, 8),
561 REPORT_COUNT(1, 1),
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),
569 REPORT_SIZE(1, 16),
570 REPORT_COUNT(1, 1),
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),
580 REPORT_SIZE(1, 16),
581 REPORT_COUNT(1, 1),
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),
591 REPORT_SIZE(1, 16),
592 REPORT_COUNT(1, 1),
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),
600 REPORT_SIZE(1, 16),
601 REPORT_COUNT(1, 1),
602 OUTPUT(1, Data|Var|Abs),
604 UNIT_EXPONENT(1, 0),
605 UNIT(1, 0), /* None */
606 END_COLLECTION,
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),
627 REPORT_SIZE(1, 8),
628 REPORT_COUNT(1, 1),
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),
637 REPORT_SIZE(1, 16),
638 REPORT_COUNT(1, 2),
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),
649 REPORT_SIZE(1, 16),
650 REPORT_COUNT(1, 2),
651 OUTPUT(1, Data|Var|Abs),
652 PHYSICAL_MAXIMUM(1, 0),
653 UNIT_EXPONENT(1, 0),
654 UNIT(1, 0),
655 END_COLLECTION,
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),
676 REPORT_SIZE(1, 8),
677 REPORT_COUNT(1, 1),
678 OUTPUT(1, Data|Var|Abs),
680 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET),
681 LOGICAL_MINIMUM(1, 0x00),
682 LOGICAL_MAXIMUM(1, 0x01),
683 REPORT_SIZE(1, 8),
684 REPORT_COUNT(1, 1),
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),
694 REPORT_SIZE(1, 16),
695 REPORT_COUNT(1, 3),
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),
707 REPORT_SIZE(1, 16),
708 REPORT_COUNT(1, 3),
709 OUTPUT(1, Data|Var|Abs),
710 PHYSICAL_MINIMUM(1, 0),
711 PHYSICAL_MAXIMUM(1, 0),
712 END_COLLECTION,
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),
733 REPORT_SIZE(1, 8),
734 REPORT_COUNT(1, 1),
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),
742 REPORT_SIZE(1, 16),
743 REPORT_COUNT(1, 1),
744 OUTPUT(1, Data|Var|Abs),
745 PHYSICAL_MINIMUM(1, 0),
746 PHYSICAL_MAXIMUM(1, 0),
747 END_COLLECTION,
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),
768 REPORT_SIZE(1, 8),
769 REPORT_COUNT(1, 1),
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),
778 REPORT_SIZE(1, 16),
779 REPORT_COUNT(1, 2),
780 OUTPUT(1, Data|Var|Abs),
781 PHYSICAL_MINIMUM(1, 0),
782 PHYSICAL_MAXIMUM(1, 0),
783 END_COLLECTION,
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),
809 REPORT_SIZE(1, 8),
810 REPORT_COUNT(1, 1),
811 OUTPUT(1, Data|Ary|Abs),
812 END_COLLECTION,
813 END_COLLECTION,
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),
829 REPORT_SIZE(1, 8),
830 REPORT_COUNT(1, 1),
831 OUTPUT(1, Data|Var|Abs),
832 PHYSICAL_MINIMUM(1, 0),
833 PHYSICAL_MAXIMUM(1, 0),
834 END_COLLECTION,
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),
848 REPORT_SIZE(1, 8),
849 REPORT_COUNT(1, 1),
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),
859 REPORT_SIZE(1, 8),
860 REPORT_COUNT(1, 1),
861 OUTPUT(1, Data|Ary|Abs),
862 END_COLLECTION,
864 USAGE(1, PID_USAGE_LOOP_COUNT),
865 LOGICAL_MINIMUM(1, 0),
866 LOGICAL_MAXIMUM(2, 0x00ff),
867 REPORT_SIZE(1, 8),
868 REPORT_COUNT(1, 1),
869 OUTPUT(1, Data|Var|Abs),
870 END_COLLECTION,
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),
884 REPORT_SIZE(1, 8),
885 REPORT_COUNT(1, 1),
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),
895 REPORT_SIZE(1, 8),
896 OUTPUT(1, Data|Ary|Abs),
897 END_COLLECTION,
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),
907 REPORT_SIZE(1, 16),
908 REPORT_COUNT(1, 4),
909 OUTPUT(1, Data|Var|Abs),
910 UNIT_EXPONENT(1, 0),
911 UNIT(1, 0), /* None */
913 USAGE(1, PID_USAGE_GAIN),
914 LOGICAL_MINIMUM(1, 0),
915 LOGICAL_MAXIMUM(1, 100),
916 REPORT_SIZE(1, 8),
917 REPORT_COUNT(1, 1),
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),
923 REPORT_SIZE(1, 8),
924 REPORT_COUNT(1, 1),
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),
933 REPORT_SIZE(1, 1),
934 REPORT_COUNT(1, 2),
935 OUTPUT(1, Data|Var|Abs),
936 END_COLLECTION,
937 USAGE(1, PID_USAGE_DIRECTION_ENABLE),
938 REPORT_COUNT(1, 1),
939 OUTPUT(1, Data|Var|Abs),
940 REPORT_COUNT(1, 5),
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),
951 REPORT_SIZE(1, 16),
952 REPORT_COUNT(1, 2),
953 OUTPUT(1, Data|Var|Abs),
954 END_COLLECTION,
955 UNIT_EXPONENT(1, 0),
956 UNIT(1, 0), /* None */
957 END_COLLECTION,
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),
973 REPORT_SIZE(1, 1),
974 REPORT_COUNT(1, 8),
975 INPUT(1, Data|Var|Abs),
977 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
978 LOGICAL_MINIMUM(1, 0),
979 LOGICAL_MAXIMUM(1, 0x7f),
980 REPORT_SIZE(1, 8),
981 REPORT_COUNT(1, 1),
982 INPUT(1, Data|Var|Abs),
983 END_COLLECTION,
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;
991 ULONG i;
993 if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header)))
994 return FALSE;
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]))
998 return FALSE;
1000 if (!hid_report_descriptor_append(desc, device_control_footer, sizeof(device_control_footer)))
1001 return FALSE;
1003 if (!hid_report_descriptor_append(desc, device_gain, sizeof(device_gain)))
1004 return FALSE;
1006 if (!hid_report_descriptor_append(desc, effect_control_header, sizeof(effect_control_header)))
1007 return FALSE;
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]))
1011 return FALSE;
1013 if (!hid_report_descriptor_append(desc, effect_control_footer, sizeof(effect_control_footer)))
1014 return FALSE;
1016 if (!hid_report_descriptor_append(desc, effect_update_header, sizeof(effect_update_header)))
1017 return FALSE;
1018 for (i = 0; i < count; ++i)
1020 if (!hid_report_descriptor_append_usage(desc, usages[i]))
1021 return FALSE;
1023 if (!hid_report_descriptor_append(desc, effect_update_footer, sizeof(effect_update_footer)))
1024 return FALSE;
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)
1038 condition = TRUE;
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))
1046 return FALSE;
1047 if (envelope && !hid_descriptor_add_set_envelope(iface))
1048 return FALSE;
1049 if (condition && !hid_descriptor_add_set_condition(iface))
1050 return FALSE;
1051 if (constant_force && !hid_descriptor_add_set_constant_force(iface))
1052 return FALSE;
1053 if (ramp_force && !hid_descriptor_add_set_ramp_force(iface))
1054 return FALSE;
1056 if (!hid_report_descriptor_append(desc, effect_state_template, sizeof(effect_state_template)))
1057 return FALSE;
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;
1072 return TRUE;
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);
1112 ULONG duration_ms;
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);
1119 else
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);
1131 USAGE control;
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;
1140 else
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;
1154 else
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);
1160 USAGE control;
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;
1169 else
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;
1176 USAGE effect_type;
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;
1185 else
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;
1211 else
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;
1229 else
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;
1244 UINT index;
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;
1251 else
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;
1273 else
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;
1288 else
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);
1296 else
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;
1317 else
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;
1341 else
1343 io->Information = 0;
1344 io->Status = STATUS_NOT_IMPLEMENTED;
1348 static const struct raw_device_vtbl raw_device_vtbl =
1350 hid_device_destroy,
1351 hid_device_start,
1352 hid_device_stop,
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;
1366 return impl;
1369 #ifdef WORDS_BIGENDIAN
1370 # define LE_ULONG(x) RtlUlongByteSwap((ULONG)(x))
1371 #else
1372 # define LE_ULONG(x) ((ULONG)(x))
1373 #endif
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);
1381 return TRUE;
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);
1390 return TRUE;
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;
1401 return TRUE;
1404 /* hatswitch x / y vs value:
1405 * -1 x +1
1406 * +-------->
1407 * -1 | 8 1 2
1408 * y | 7 0 3
1409 * +1 | 6 5 4
1412 static void hatswitch_decompose(BYTE value, LONG *x, LONG *y)
1414 *x = *y = 0;
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;
1438 LONG x, y;
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]);
1442 return TRUE;
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;
1449 LONG x, y;
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]);
1453 return TRUE;
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;
1460 LONG old_x, old_y;
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]);
1464 return TRUE;
1467 BOOL hid_device_sync_report(struct unix_device *iface)
1469 BOOL dropped;
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);
1474 else
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;
1479 return !dropped;
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;