include: Add STORAGE_HOTPLUG_INFO structure.
[wine.git] / dlls / winebus.sys / hid.c
blobd31718c62938200b6a5fb9b4c2227094bb75495c
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 + 4 * (count + 1) > 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 += 4 * count;
219 if (count % 2) iface->hid_device_state.bit_size += 4;
220 return TRUE;
223 return FALSE;
226 BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
228 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
229 const BYTE template[] =
231 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
232 USAGE(1, HID_USAGE_GENERIC_HATSWITCH),
233 LOGICAL_MINIMUM(1, 1),
234 LOGICAL_MAXIMUM(1, 8),
235 REPORT_SIZE(1, 4),
236 REPORT_COUNT(4, count),
237 UNIT(1, 0x0), /* None */
238 INPUT(1, Data|Var|Abs|Null),
240 const BYTE template_pad[] =
242 REPORT_COUNT(1, 4),
243 REPORT_SIZE(1, 1),
244 INPUT(1, Cnst|Ary|Abs),
247 if (!hid_device_add_hatswitch_count(iface, count))
248 return FALSE;
250 if (!hid_report_descriptor_append(desc, template, sizeof(template)))
251 return FALSE;
253 if ((count % 2) && !hid_report_descriptor_append(desc, template_pad, sizeof(template_pad)))
254 return FALSE;
256 return TRUE;
259 static BOOL hid_device_add_axis_count(struct unix_device *iface, BOOL rel, BYTE count,
260 USAGE usage_page, const USAGE *usages)
262 struct hid_device_state *state = &iface->hid_device_state;
263 USHORT i, offset = state->bit_size / 8;
265 if (!rel && state->rel_axis_count)
266 ERR("absolute axes should be added before relative axes!\n");
267 else if (state->button_count || state->hatswitch_count)
268 ERR("axes should be added before buttons or hatswitches!\n");
269 else if ((state->bit_size % 8))
270 ERR("axes should be byte aligned, missing padding!\n");
271 else if (state->bit_size + 32 * count > 0x80000)
272 ERR("report size overflow, too many elements!\n");
273 else if (rel)
275 if (!state->rel_axis_count) state->rel_axis_start = offset;
276 state->rel_axis_count += count;
277 state->bit_size += 32 * count;
278 return TRUE;
280 else
282 if (state->abs_axis_count + count > ARRAY_SIZE(state->abs_axis_usages))
284 ERR("absolute axis usage overflow, too many elements!\n");
285 return FALSE;
287 for (i = 0; i < count; ++i)
289 state->abs_axis_usages[state->abs_axis_count + i].UsagePage = usage_page;
290 state->abs_axis_usages[state->abs_axis_count + i].Usage = usages[i];
293 if (!state->abs_axis_count) state->abs_axis_start = offset;
294 state->abs_axis_count += count;
295 state->bit_size += 32 * count;
296 return TRUE;
299 return FALSE;
302 BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page,
303 const USAGE *usages, BOOL rel, LONG min, LONG max)
305 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
306 const BYTE template_begin[] =
308 USAGE_PAGE(1, usage_page),
309 COLLECTION(1, Physical),
311 const BYTE template_end[] =
313 END_COLLECTION,
315 const BYTE template[] =
317 LOGICAL_MINIMUM(4, min),
318 LOGICAL_MAXIMUM(4, max),
319 REPORT_SIZE(1, 32),
320 REPORT_COUNT(1, count),
321 INPUT(1, Data|Var|(rel ? Rel : Abs)),
323 int i;
325 if (!hid_device_add_axis_count(iface, rel, count, usage_page, usages))
326 return FALSE;
328 if (!hid_report_descriptor_append(desc, template_begin, sizeof(template_begin)))
329 return FALSE;
331 for (i = 0; i < count; i++)
333 if (!hid_report_descriptor_append_usage(desc, usages[i]))
334 return FALSE;
337 if (!hid_report_descriptor_append(desc, template, sizeof(template)))
338 return FALSE;
340 if (!hid_report_descriptor_append(desc, template_end, sizeof(template_end)))
341 return FALSE;
343 return TRUE;
346 #include "pshpack1.h"
347 struct hid_haptics_intensity
349 UINT16 rumble_intensity;
350 UINT16 buzz_intensity;
351 UINT16 left_intensity;
352 UINT16 right_intensity;
354 #include "poppack.h"
356 BOOL hid_device_add_haptics(struct unix_device *iface)
358 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
359 const BYTE haptics_features_report = ++desc->next_report_id[HidP_Feature];
360 const BYTE haptics_intensity_report = ++desc->next_report_id[HidP_Output];
361 const BYTE haptics_template[] =
363 USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS),
364 USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER),
365 COLLECTION(1, Logical),
366 REPORT_ID(1, haptics_features_report),
368 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST),
369 COLLECTION(1, NamedArray),
370 /* ordinal 1 and 2 are reserved for implicit waveforms */
371 USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3),
372 REPORT_SIZE(1, 16),
373 REPORT_COUNT(1, 1),
374 FEATURE(1, Data|Var|Abs|Null),
375 END_COLLECTION,
377 USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST),
378 COLLECTION(1, NamedArray),
379 /* ordinal 1 and 2 are reserved for implicit waveforms */
380 USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3),
381 REPORT_SIZE(1, 16),
382 REPORT_COUNT(1, 1),
383 FEATURE(1, Data|Var|Abs|Null),
384 END_COLLECTION,
386 USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME),
387 UNIT(2, 0x1001), /* seconds */
388 UNIT_EXPONENT(1, -3), /* 10^-3 */
389 LOGICAL_MINIMUM(4, 0x00000000),
390 LOGICAL_MAXIMUM(4, 0x7fffffff),
391 REPORT_SIZE(1, 32),
392 REPORT_COUNT(1, 1),
393 FEATURE(1, Data|Var|Abs),
394 /* reset global items */
395 UNIT(1, 0), /* None */
396 UNIT_EXPONENT(1, 0),
398 REPORT_ID(1, haptics_intensity_report),
399 USAGE(1, HID_USAGE_HAPTICS_INTENSITY),
400 LOGICAL_MINIMUM(4, 0x00000000),
401 LOGICAL_MAXIMUM(4, 0x0000ffff),
402 REPORT_SIZE(1, 16),
403 REPORT_COUNT(1, 1),
404 OUTPUT(1, Data|Var|Abs),
405 END_COLLECTION,
407 const BYTE trigger_template_begin[] =
409 USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
410 COLLECTION(1, Physical),
412 const BYTE trigger_template_end[] =
414 END_COLLECTION,
417 iface->hid_haptics.features_report = haptics_features_report;
418 iface->hid_haptics.intensity_report = haptics_intensity_report;
419 iface->hid_haptics.features.rumble.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE;
420 iface->hid_haptics.features.rumble.duration = 0;
421 iface->hid_haptics.features.rumble.cutoff_time_ms = 1000;
422 iface->hid_haptics.features.buzz.waveform = HID_USAGE_HAPTICS_WAVEFORM_BUZZ;
423 iface->hid_haptics.features.buzz.duration = 0;
424 iface->hid_haptics.features.buzz.cutoff_time_ms = 1000;
425 iface->hid_haptics.features.left.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE;
426 iface->hid_haptics.features.left.duration = 0;
427 iface->hid_haptics.features.left.cutoff_time_ms = 1000;
428 iface->hid_haptics.features.right.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE;
429 iface->hid_haptics.features.right.duration = 0;
430 iface->hid_haptics.features.right.cutoff_time_ms = 1000;
432 if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
433 return FALSE;
434 if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
435 return FALSE;
437 if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_Z))
438 return FALSE;
439 if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin)))
440 return FALSE;
441 if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
442 return FALSE;
443 if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end)))
444 return FALSE;
446 if (!hid_report_descriptor_append_usage(desc, HID_USAGE_GENERIC_RZ))
447 return FALSE;
448 if (!hid_report_descriptor_append(desc, trigger_template_begin, sizeof(trigger_template_begin)))
449 return FALSE;
450 if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
451 return FALSE;
452 if (!hid_report_descriptor_append(desc, trigger_template_end, sizeof(trigger_template_end)))
453 return FALSE;
455 return TRUE;
458 #include "pshpack1.h"
459 struct pid_device_control
461 BYTE control_index;
464 static const USAGE pid_device_control_usages[] =
466 0, /* HID nary collection indexes start at 1 */
467 PID_USAGE_DC_ENABLE_ACTUATORS,
468 PID_USAGE_DC_DISABLE_ACTUATORS,
469 PID_USAGE_DC_STOP_ALL_EFFECTS,
470 PID_USAGE_DC_DEVICE_RESET,
471 PID_USAGE_DC_DEVICE_PAUSE,
472 PID_USAGE_DC_DEVICE_CONTINUE,
475 struct pid_device_gain
477 BYTE value;
480 struct pid_effect_control
482 BYTE index;
483 BYTE control_index;
484 BYTE iterations;
487 static const USAGE pid_effect_control_usages[] =
489 0, /* HID nary collection indexes start at 1 */
490 PID_USAGE_OP_EFFECT_START,
491 PID_USAGE_OP_EFFECT_START_SOLO,
492 PID_USAGE_OP_EFFECT_STOP,
495 struct pid_effect_update
497 BYTE index;
498 BYTE type_index;
499 UINT16 duration;
500 UINT16 trigger_repeat_interval;
501 UINT16 sample_period;
502 UINT16 start_delay;
503 BYTE gain_percent;
504 BYTE trigger_button;
505 BYTE enable_bits;
506 UINT16 direction[2];
509 struct pid_set_periodic
511 BYTE index;
512 UINT16 magnitude;
513 INT16 offset;
514 UINT16 phase;
515 UINT16 period;
518 struct pid_set_envelope
520 BYTE index;
521 UINT16 attack_level;
522 UINT16 fade_level;
523 UINT16 attack_time;
524 UINT16 fade_time;
527 struct pid_set_condition
529 BYTE index;
530 BYTE condition_index;
531 INT16 center_point_offset;
532 INT16 positive_coefficient;
533 INT16 negative_coefficient;
534 UINT16 positive_saturation;
535 UINT16 negative_saturation;
536 UINT16 dead_band;
539 struct pid_set_constant_force
541 BYTE index;
542 INT16 magnitude;
545 struct pid_set_ramp_force
547 BYTE index;
548 INT16 ramp_start;
549 INT16 ramp_end;
552 struct pid_effect_state
554 BYTE flags;
555 BYTE index;
557 #include "poppack.h"
559 static BOOL hid_descriptor_add_set_periodic(struct unix_device *iface)
561 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
562 const BYTE report_id = ++desc->next_report_id[HidP_Output];
563 const BYTE template[] =
565 /* Periodic Report Definition */
566 USAGE(1, PID_USAGE_SET_PERIODIC_REPORT),
567 COLLECTION(1, Logical),
568 REPORT_ID(1, report_id),
570 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
571 LOGICAL_MINIMUM(1, 0),
572 LOGICAL_MAXIMUM(1, 0x7f),
573 REPORT_SIZE(1, 8),
574 REPORT_COUNT(1, 1),
575 OUTPUT(1, Data|Var|Abs),
577 USAGE(1, PID_USAGE_MAGNITUDE),
578 LOGICAL_MINIMUM(1, 0),
579 LOGICAL_MAXIMUM(2, 0x7fff),
580 PHYSICAL_MINIMUM(1, 0),
581 PHYSICAL_MAXIMUM(2, 10000),
582 REPORT_SIZE(1, 16),
583 REPORT_COUNT(1, 1),
584 OUTPUT(1, Data|Var|Abs),
585 PHYSICAL_MINIMUM(1, 0),
586 PHYSICAL_MAXIMUM(1, 0),
588 USAGE(1, PID_USAGE_OFFSET),
589 LOGICAL_MINIMUM(2, 0x8000),
590 LOGICAL_MAXIMUM(2, 0x7fff),
591 PHYSICAL_MINIMUM(2, -10000),
592 PHYSICAL_MAXIMUM(2, +10000),
593 REPORT_SIZE(1, 16),
594 REPORT_COUNT(1, 1),
595 OUTPUT(1, Data|Var|Abs),
596 PHYSICAL_MINIMUM(1, 0),
597 PHYSICAL_MAXIMUM(1, 0),
599 USAGE(1, PID_USAGE_PHASE),
600 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
601 UNIT_EXPONENT(1, -2),
602 LOGICAL_MINIMUM(1, 0),
603 LOGICAL_MAXIMUM(4, 36000),
604 REPORT_SIZE(1, 16),
605 REPORT_COUNT(1, 1),
606 OUTPUT(1, Data|Var|Abs),
608 USAGE(1, PID_USAGE_PERIOD),
609 UNIT(2, 0x1003), /* Eng Lin:Time */
610 UNIT_EXPONENT(1, -3), /* 10^-3 */
611 LOGICAL_MINIMUM(1, 0),
612 LOGICAL_MAXIMUM(2, 0x7fff),
613 REPORT_SIZE(1, 16),
614 REPORT_COUNT(1, 1),
615 OUTPUT(1, Data|Var|Abs),
617 UNIT_EXPONENT(1, 0),
618 UNIT(1, 0), /* None */
619 END_COLLECTION,
622 iface->hid_physical.set_periodic_report = report_id;
623 return hid_report_descriptor_append(desc, template, sizeof(template));
626 static BOOL hid_descriptor_add_set_envelope(struct unix_device *iface)
628 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
629 const BYTE report_id = ++desc->next_report_id[HidP_Output];
630 const BYTE template[] =
632 /* Envelope Report Definition */
633 USAGE(1, PID_USAGE_SET_ENVELOPE_REPORT),
634 COLLECTION(1, Logical),
635 REPORT_ID(1, report_id),
637 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
638 LOGICAL_MINIMUM(1, 0),
639 LOGICAL_MAXIMUM(1, 0x7f),
640 REPORT_SIZE(1, 8),
641 REPORT_COUNT(1, 1),
642 OUTPUT(1, Data|Var|Abs),
644 USAGE(1, PID_USAGE_ATTACK_LEVEL),
645 USAGE(1, PID_USAGE_FADE_LEVEL),
646 LOGICAL_MINIMUM(1, 0),
647 LOGICAL_MAXIMUM(2, 0x7fff),
648 PHYSICAL_MINIMUM(1, 0),
649 PHYSICAL_MAXIMUM(2, 10000),
650 REPORT_SIZE(1, 16),
651 REPORT_COUNT(1, 2),
652 OUTPUT(1, Data|Var|Abs),
653 PHYSICAL_MINIMUM(1, 0),
654 PHYSICAL_MAXIMUM(1, 0),
656 USAGE(1, PID_USAGE_ATTACK_TIME),
657 USAGE(1, PID_USAGE_FADE_TIME),
658 UNIT(2, 0x1003), /* Eng Lin:Time */
659 UNIT_EXPONENT(1, -3),
660 LOGICAL_MINIMUM(1, 0),
661 LOGICAL_MAXIMUM(2, 0x7fff),
662 REPORT_SIZE(1, 16),
663 REPORT_COUNT(1, 2),
664 OUTPUT(1, Data|Var|Abs),
665 PHYSICAL_MAXIMUM(1, 0),
666 UNIT_EXPONENT(1, 0),
667 UNIT(1, 0),
668 END_COLLECTION,
671 iface->hid_physical.set_envelope_report = report_id;
672 return hid_report_descriptor_append(desc, template, sizeof(template));
675 static BOOL hid_descriptor_add_set_condition(struct unix_device *iface)
677 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
678 const BYTE report_id = ++desc->next_report_id[HidP_Output];
679 const BYTE template[] =
681 /* Condition Report Definition */
682 USAGE(1, PID_USAGE_SET_CONDITION_REPORT),
683 COLLECTION(1, Logical),
684 REPORT_ID(1, report_id),
686 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
687 LOGICAL_MINIMUM(1, 0),
688 LOGICAL_MAXIMUM(1, 0x7f),
689 REPORT_SIZE(1, 8),
690 REPORT_COUNT(1, 1),
691 OUTPUT(1, Data|Var|Abs),
693 USAGE(1, PID_USAGE_PARAMETER_BLOCK_OFFSET),
694 LOGICAL_MINIMUM(1, 0x00),
695 LOGICAL_MAXIMUM(1, 0x01),
696 REPORT_SIZE(1, 8),
697 REPORT_COUNT(1, 1),
698 OUTPUT(1, Data|Var|Abs),
700 USAGE(1, PID_USAGE_CP_OFFSET),
701 USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT),
702 USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT),
703 LOGICAL_MINIMUM(2, 0x8000),
704 LOGICAL_MAXIMUM(2, 0x7fff),
705 PHYSICAL_MINIMUM(2, -10000),
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),
713 USAGE(1, PID_USAGE_POSITIVE_SATURATION),
714 USAGE(1, PID_USAGE_NEGATIVE_SATURATION),
715 USAGE(1, PID_USAGE_DEAD_BAND),
716 LOGICAL_MINIMUM(1, 0),
717 LOGICAL_MAXIMUM(4, 0xffff),
718 PHYSICAL_MINIMUM(1, 0),
719 PHYSICAL_MAXIMUM(2, +10000),
720 REPORT_SIZE(1, 16),
721 REPORT_COUNT(1, 3),
722 OUTPUT(1, Data|Var|Abs),
723 PHYSICAL_MINIMUM(1, 0),
724 PHYSICAL_MAXIMUM(1, 0),
725 END_COLLECTION,
728 iface->hid_physical.set_condition_report = report_id;
729 return hid_report_descriptor_append(desc, template, sizeof(template));
732 static BOOL hid_descriptor_add_set_constant_force(struct unix_device *iface)
734 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
735 const BYTE report_id = ++desc->next_report_id[HidP_Output];
736 const BYTE template[] =
738 /* Constant Force Report Definition */
739 USAGE(1, PID_USAGE_SET_CONSTANT_FORCE_REPORT),
740 COLLECTION(1, Logical),
741 REPORT_ID(1, report_id),
743 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
744 LOGICAL_MINIMUM(1, 0),
745 LOGICAL_MAXIMUM(1, 0x7f),
746 REPORT_SIZE(1, 8),
747 REPORT_COUNT(1, 1),
748 OUTPUT(1, Data|Var|Abs),
750 USAGE(1, PID_USAGE_MAGNITUDE),
751 LOGICAL_MINIMUM(2, 0x8000),
752 LOGICAL_MAXIMUM(2, 0x7fff),
753 PHYSICAL_MINIMUM(2, -10000),
754 PHYSICAL_MAXIMUM(2, +10000),
755 REPORT_SIZE(1, 16),
756 REPORT_COUNT(1, 1),
757 OUTPUT(1, Data|Var|Abs),
758 PHYSICAL_MINIMUM(1, 0),
759 PHYSICAL_MAXIMUM(1, 0),
760 END_COLLECTION,
763 iface->hid_physical.set_constant_force_report = report_id;
764 return hid_report_descriptor_append(desc, template, sizeof(template));
767 static BOOL hid_descriptor_add_set_ramp_force(struct unix_device *iface)
769 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
770 const BYTE report_id = ++desc->next_report_id[HidP_Output];
771 const BYTE template[] =
773 /* Ramp Force Report Definition */
774 USAGE(1, PID_USAGE_SET_RAMP_FORCE_REPORT),
775 COLLECTION(1, Logical),
776 REPORT_ID(1, report_id),
778 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
779 LOGICAL_MINIMUM(1, 0),
780 LOGICAL_MAXIMUM(1, 0x7f),
781 REPORT_SIZE(1, 8),
782 REPORT_COUNT(1, 1),
783 OUTPUT(1, Data|Var|Abs),
785 USAGE(1, PID_USAGE_RAMP_START),
786 USAGE(1, PID_USAGE_RAMP_END),
787 LOGICAL_MINIMUM(2, 0x8000),
788 LOGICAL_MAXIMUM(2, 0x7fff),
789 PHYSICAL_MINIMUM(2, -10000),
790 PHYSICAL_MAXIMUM(2, +10000),
791 REPORT_SIZE(1, 16),
792 REPORT_COUNT(1, 2),
793 OUTPUT(1, Data|Var|Abs),
794 PHYSICAL_MINIMUM(1, 0),
795 PHYSICAL_MAXIMUM(1, 0),
796 END_COLLECTION,
799 iface->hid_physical.set_ramp_force_report = report_id;
800 return hid_report_descriptor_append(desc, template, sizeof(template));
803 BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count)
805 struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
806 const BYTE device_control_report = ++desc->next_report_id[HidP_Output];
807 struct hid_device_state *state = &iface->hid_device_state;
808 const BYTE device_control_header[] =
810 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
811 USAGE(1, PID_USAGE_DEVICE_CONTROL_REPORT),
812 COLLECTION(1, Logical),
813 REPORT_ID(1, device_control_report),
815 USAGE(1, PID_USAGE_DEVICE_CONTROL),
816 COLLECTION(1, Logical),
818 const BYTE device_control_footer[] =
820 LOGICAL_MINIMUM(1, 1),
821 LOGICAL_MAXIMUM(1, 6),
822 REPORT_SIZE(1, 8),
823 REPORT_COUNT(1, 1),
824 OUTPUT(1, Data|Ary|Abs),
825 END_COLLECTION,
826 END_COLLECTION,
829 const BYTE device_gain_report = ++desc->next_report_id[HidP_Output];
830 const BYTE device_gain[] =
832 USAGE_PAGE(1, HID_USAGE_PAGE_PID),
833 USAGE(1, PID_USAGE_DEVICE_GAIN_REPORT),
834 COLLECTION(1, Logical),
835 REPORT_ID(1, device_gain_report),
837 USAGE(1, PID_USAGE_DEVICE_GAIN),
838 LOGICAL_MINIMUM(1, 0),
839 LOGICAL_MAXIMUM(1, 100),
840 PHYSICAL_MINIMUM(1, 0),
841 PHYSICAL_MAXIMUM(2, 10000),
842 REPORT_SIZE(1, 8),
843 REPORT_COUNT(1, 1),
844 OUTPUT(1, Data|Var|Abs),
845 PHYSICAL_MINIMUM(1, 0),
846 PHYSICAL_MAXIMUM(1, 0),
847 END_COLLECTION,
850 const BYTE effect_control_report = ++desc->next_report_id[HidP_Output];
851 const BYTE effect_control_header[] =
853 /* Control effect state */
854 USAGE(1, PID_USAGE_EFFECT_OPERATION_REPORT),
855 COLLECTION(1, Logical),
856 REPORT_ID(1, effect_control_report),
858 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
859 LOGICAL_MINIMUM(1, 0),
860 LOGICAL_MAXIMUM(1, 0x7f),
861 REPORT_SIZE(1, 8),
862 REPORT_COUNT(1, 1),
863 OUTPUT(1, Data|Var|Abs),
865 USAGE(1, PID_USAGE_EFFECT_OPERATION),
866 COLLECTION(1, Logical),
868 const BYTE effect_control_footer[] =
870 LOGICAL_MINIMUM(1, 1),
871 LOGICAL_MAXIMUM(1, 3),
872 REPORT_SIZE(1, 8),
873 REPORT_COUNT(1, 1),
874 OUTPUT(1, Data|Ary|Abs),
875 END_COLLECTION,
877 USAGE(1, PID_USAGE_LOOP_COUNT),
878 LOGICAL_MINIMUM(1, 0),
879 LOGICAL_MAXIMUM(2, 0x00ff),
880 REPORT_SIZE(1, 8),
881 REPORT_COUNT(1, 1),
882 OUTPUT(1, Data|Var|Abs),
883 END_COLLECTION,
886 const BYTE effect_update_report = ++desc->next_report_id[HidP_Output];
887 const BYTE effect_update_header[] =
889 /* Set effect properties */
890 USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
891 COLLECTION(1, Logical),
892 REPORT_ID(1, effect_update_report),
894 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
895 LOGICAL_MINIMUM(1, 0),
896 LOGICAL_MAXIMUM(1, 0x7f),
897 REPORT_SIZE(1, 8),
898 REPORT_COUNT(1, 1),
899 OUTPUT(1, Data|Var|Abs),
901 USAGE(1, PID_USAGE_EFFECT_TYPE),
902 COLLECTION(1, Logical),
904 const BYTE effect_update_footer[] =
906 LOGICAL_MINIMUM(1, 1),
907 LOGICAL_MAXIMUM(1, count),
908 REPORT_SIZE(1, 8),
909 OUTPUT(1, Data|Ary|Abs),
910 END_COLLECTION,
912 USAGE(1, PID_USAGE_DURATION),
913 USAGE(1, PID_USAGE_TRIGGER_REPEAT_INTERVAL),
914 USAGE(1, PID_USAGE_SAMPLE_PERIOD),
915 USAGE(1, PID_USAGE_START_DELAY),
916 UNIT(2, 0x1003), /* Eng Lin:Time */
917 UNIT_EXPONENT(1, -3), /* 10^-3 */
918 LOGICAL_MINIMUM(1, 0),
919 LOGICAL_MAXIMUM(2, 0x7fff),
920 REPORT_SIZE(1, 16),
921 REPORT_COUNT(1, 4),
922 OUTPUT(1, Data|Var|Abs),
923 UNIT_EXPONENT(1, 0),
924 UNIT(1, 0), /* None */
926 USAGE(1, PID_USAGE_GAIN),
927 LOGICAL_MINIMUM(1, 0),
928 LOGICAL_MAXIMUM(1, 100),
929 REPORT_SIZE(1, 8),
930 REPORT_COUNT(1, 1),
931 OUTPUT(1, Data|Var|Abs|Null),
933 USAGE(1, PID_USAGE_TRIGGER_BUTTON),
934 LOGICAL_MINIMUM(1, 0),
935 LOGICAL_MAXIMUM(2, state->button_count),
936 REPORT_SIZE(1, 8),
937 REPORT_COUNT(1, 1),
938 OUTPUT(1, Data|Var|Abs|Null),
940 USAGE(1, PID_USAGE_AXES_ENABLE),
941 COLLECTION(1, Logical),
942 USAGE(4, (state->abs_axis_usages[0].UsagePage<<16)|state->abs_axis_usages[0].Usage),
943 USAGE(4, (state->abs_axis_usages[1].UsagePage<<16)|state->abs_axis_usages[1].Usage),
944 LOGICAL_MINIMUM(1, 0),
945 LOGICAL_MAXIMUM(1, 1),
946 REPORT_SIZE(1, 1),
947 REPORT_COUNT(1, 2),
948 OUTPUT(1, Data|Var|Abs),
949 END_COLLECTION,
950 USAGE(1, PID_USAGE_DIRECTION_ENABLE),
951 REPORT_COUNT(1, 1),
952 OUTPUT(1, Data|Var|Abs),
953 REPORT_COUNT(1, 5),
954 OUTPUT(1, Cnst|Var|Abs), /* 5-bit pad */
956 USAGE(1, PID_USAGE_DIRECTION),
957 COLLECTION(1, Logical),
958 USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|1),
959 USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|2),
960 UNIT(1, 0x14), /* Eng Rot:Angular Pos */
961 UNIT_EXPONENT(1, -2),
962 LOGICAL_MINIMUM(1, 0),
963 LOGICAL_MAXIMUM(4, 36000),
964 REPORT_SIZE(1, 16),
965 REPORT_COUNT(1, 2),
966 OUTPUT(1, Data|Var|Abs),
967 END_COLLECTION,
968 UNIT_EXPONENT(1, 0),
969 UNIT(1, 0), /* None */
970 END_COLLECTION,
973 const BYTE effect_state_report = ++desc->next_report_id[HidP_Input];
974 const BYTE effect_state_template[] =
976 /* Report effect state */
977 USAGE(1, PID_USAGE_STATE_REPORT),
978 COLLECTION(1, Logical),
979 REPORT_ID(1, effect_state_report),
981 USAGE(1, PID_USAGE_DEVICE_PAUSED),
982 USAGE(1, PID_USAGE_ACTUATORS_ENABLED),
983 USAGE(1, PID_USAGE_EFFECT_PLAYING),
984 LOGICAL_MINIMUM(1, 0),
985 LOGICAL_MAXIMUM(1, 1),
986 REPORT_SIZE(1, 1),
987 REPORT_COUNT(1, 8),
988 INPUT(1, Data|Var|Abs),
990 USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
991 LOGICAL_MINIMUM(1, 0),
992 LOGICAL_MAXIMUM(1, 0x7f),
993 REPORT_SIZE(1, 8),
994 REPORT_COUNT(1, 1),
995 INPUT(1, Data|Var|Abs),
996 END_COLLECTION,
998 struct hid_effect_state *effect_state = &iface->hid_physical.effect_state;
999 BOOL periodic = FALSE;
1000 BOOL envelope = FALSE;
1001 BOOL condition = FALSE;
1002 BOOL constant_force = FALSE;
1003 BOOL ramp_force = FALSE;
1004 ULONG i;
1006 if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header)))
1007 return FALSE;
1008 for (i = 1; i < ARRAY_SIZE(pid_device_control_usages); ++i)
1010 if (!hid_report_descriptor_append_usage(desc, pid_device_control_usages[i]))
1011 return FALSE;
1013 if (!hid_report_descriptor_append(desc, device_control_footer, sizeof(device_control_footer)))
1014 return FALSE;
1016 if (!hid_report_descriptor_append(desc, device_gain, sizeof(device_gain)))
1017 return FALSE;
1019 if (!hid_report_descriptor_append(desc, effect_control_header, sizeof(effect_control_header)))
1020 return FALSE;
1021 for (i = 1; i < ARRAY_SIZE(pid_effect_control_usages); ++i)
1023 if (!hid_report_descriptor_append_usage(desc, pid_effect_control_usages[i]))
1024 return FALSE;
1026 if (!hid_report_descriptor_append(desc, effect_control_footer, sizeof(effect_control_footer)))
1027 return FALSE;
1029 if (!hid_report_descriptor_append(desc, effect_update_header, sizeof(effect_update_header)))
1030 return FALSE;
1031 for (i = 0; i < count; ++i)
1033 if (!hid_report_descriptor_append_usage(desc, usages[i]))
1034 return FALSE;
1036 if (!hid_report_descriptor_append(desc, effect_update_footer, sizeof(effect_update_footer)))
1037 return FALSE;
1039 for (i = 0; i < count; ++i)
1041 if (usages[i] == PID_USAGE_ET_SINE ||
1042 usages[i] == PID_USAGE_ET_SQUARE ||
1043 usages[i] == PID_USAGE_ET_TRIANGLE ||
1044 usages[i] == PID_USAGE_ET_SAWTOOTH_UP ||
1045 usages[i] == PID_USAGE_ET_SAWTOOTH_DOWN)
1046 periodic = envelope = TRUE;
1047 if (usages[i] == PID_USAGE_ET_SPRING ||
1048 usages[i] == PID_USAGE_ET_DAMPER ||
1049 usages[i] == PID_USAGE_ET_INERTIA ||
1050 usages[i] == PID_USAGE_ET_FRICTION)
1051 condition = TRUE;
1052 if (usages[i] == PID_USAGE_ET_CONSTANT_FORCE)
1053 envelope = constant_force = TRUE;
1054 if (usages[i] == PID_USAGE_ET_RAMP)
1055 envelope = ramp_force = TRUE;
1058 if (periodic && !hid_descriptor_add_set_periodic(iface))
1059 return FALSE;
1060 if (envelope && !hid_descriptor_add_set_envelope(iface))
1061 return FALSE;
1062 if (condition && !hid_descriptor_add_set_condition(iface))
1063 return FALSE;
1064 if (constant_force && !hid_descriptor_add_set_constant_force(iface))
1065 return FALSE;
1066 if (ramp_force && !hid_descriptor_add_set_ramp_force(iface))
1067 return FALSE;
1069 if (!hid_report_descriptor_append(desc, effect_state_template, sizeof(effect_state_template)))
1070 return FALSE;
1072 /* HID nary collection indexes start at 1 */
1073 memcpy(iface->hid_physical.effect_types + 1, usages, count * sizeof(*usages));
1075 iface->hid_physical.device_control_report = device_control_report;
1076 iface->hid_physical.device_gain_report = device_gain_report;
1077 iface->hid_physical.effect_control_report = effect_control_report;
1078 iface->hid_physical.effect_update_report = effect_update_report;
1080 effect_state->id = effect_state_report;
1081 effect_state->report_len = sizeof(struct pid_effect_state) + 1;
1082 if (!(effect_state->report_buf = calloc(1, effect_state->report_len))) return FALSE;
1083 effect_state->report_buf[0] = effect_state->id;
1085 return TRUE;
1088 #include "pop_hid_macros.h"
1090 static void hid_device_destroy(struct unix_device *iface)
1092 iface->hid_vtbl->destroy(iface);
1093 free(iface->hid_report_descriptor.data);
1094 free(iface->hid_device_state.report_buf);
1095 free(iface->hid_device_state.last_report_buf);
1098 static NTSTATUS hid_device_start(struct unix_device *iface)
1100 return iface->hid_vtbl->start(iface);
1103 static void hid_device_stop(struct unix_device *iface)
1105 iface->hid_vtbl->stop(iface);
1108 static NTSTATUS hid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer, UINT length, UINT *out_length)
1110 *out_length = iface->hid_report_descriptor.size;
1111 if (length < iface->hid_report_descriptor.size) return STATUS_BUFFER_TOO_SMALL;
1113 memcpy(buffer, iface->hid_report_descriptor.data, iface->hid_report_descriptor.size);
1114 return STATUS_SUCCESS;
1117 static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
1119 struct hid_physical *physical = &iface->hid_physical;
1120 struct hid_haptics *haptics = &iface->hid_haptics;
1122 if (packet->reportId == haptics->intensity_report)
1124 struct hid_haptics_intensity *report = (struct hid_haptics_intensity *)(packet->reportBuffer + 1);
1125 ULONG duration_ms;
1127 io->Information = sizeof(*report) + 1;
1128 assert(packet->reportBufferLen == io->Information);
1130 if (!report->rumble_intensity && !report->buzz_intensity && !report->left_intensity && !report->right_intensity)
1131 io->Status = iface->hid_vtbl->haptics_stop(iface);
1132 else
1134 duration_ms = min(haptics->features.rumble.cutoff_time_ms, haptics->features.buzz.cutoff_time_ms);
1135 duration_ms = min(duration_ms, haptics->features.left.cutoff_time_ms);
1136 duration_ms = min(duration_ms, haptics->features.right.cutoff_time_ms);
1137 io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity,
1138 report->left_intensity, report->right_intensity);
1141 else if (packet->reportId == physical->device_control_report)
1143 struct pid_device_control *report = (struct pid_device_control *)(packet->reportBuffer + 1);
1144 USAGE control;
1146 io->Information = sizeof(*report) + 1;
1147 if (packet->reportBufferLen < io->Information)
1148 io->Status = STATUS_BUFFER_TOO_SMALL;
1149 else if (report->control_index >= ARRAY_SIZE(pid_device_control_usages))
1150 io->Status = STATUS_INVALID_PARAMETER;
1151 else if (!(control = pid_device_control_usages[report->control_index]))
1152 io->Status = STATUS_INVALID_PARAMETER;
1153 else
1155 io->Status = iface->hid_vtbl->physical_device_control(iface, control);
1156 if (control == PID_USAGE_DC_DEVICE_RESET && io->Status == STATUS_SUCCESS)
1157 memset(physical->effect_params, 0, sizeof(physical->effect_params));
1160 else if (packet->reportId == physical->device_gain_report)
1162 struct pid_device_gain *report = (struct pid_device_gain *)(packet->reportBuffer + 1);
1164 io->Information = sizeof(*report) + 1;
1165 if (packet->reportBufferLen < io->Information)
1166 io->Status = STATUS_BUFFER_TOO_SMALL;
1167 else
1168 io->Status = iface->hid_vtbl->physical_device_set_gain(iface, report->value);
1170 else if (packet->reportId == physical->effect_control_report)
1172 struct pid_effect_control *report = (struct pid_effect_control *)(packet->reportBuffer + 1);
1173 USAGE control;
1175 io->Information = sizeof(*report) + 1;
1176 if (packet->reportBufferLen < io->Information)
1177 io->Status = STATUS_BUFFER_TOO_SMALL;
1178 else if (report->control_index >= ARRAY_SIZE(pid_effect_control_usages))
1179 io->Status = STATUS_INVALID_PARAMETER;
1180 else if (!(control = pid_effect_control_usages[report->control_index]))
1181 io->Status = STATUS_INVALID_PARAMETER;
1182 else
1183 io->Status = iface->hid_vtbl->physical_effect_control(iface, report->index, control, report->iterations);
1185 else if (packet->reportId == physical->effect_update_report)
1187 struct pid_effect_update *report = (struct pid_effect_update *)(packet->reportBuffer + 1);
1188 struct effect_params *params = iface->hid_physical.effect_params + report->index;
1189 USAGE effect_type;
1191 io->Information = sizeof(*report) + 1;
1192 if (packet->reportBufferLen < io->Information)
1193 io->Status = STATUS_BUFFER_TOO_SMALL;
1194 else if (report->type_index >= ARRAY_SIZE(iface->hid_physical.effect_types))
1195 io->Status = STATUS_INVALID_PARAMETER;
1196 else if (!(effect_type = iface->hid_physical.effect_types[report->type_index]))
1197 io->Status = STATUS_INVALID_PARAMETER;
1198 else
1200 params->effect_type = effect_type;
1201 params->duration = report->duration;
1202 params->trigger_repeat_interval = report->trigger_repeat_interval;
1203 params->sample_period = report->sample_period;
1204 params->start_delay = report->start_delay;
1205 params->gain_percent = report->gain_percent;
1206 params->trigger_button = report->trigger_button == 0xff ? 0 : report->trigger_button;
1207 params->axis_enabled[0] = (report->enable_bits & 1) != 0;
1208 params->axis_enabled[1] = (report->enable_bits & 2) != 0;
1209 params->direction_enabled = (report->enable_bits & 4) != 0;
1210 params->direction[0] = report->direction[0];
1211 params->direction[1] = report->direction[1];
1213 io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
1216 else if (packet->reportId == physical->set_periodic_report)
1218 struct pid_set_periodic *report = (struct pid_set_periodic *)(packet->reportBuffer + 1);
1219 struct effect_params *params = iface->hid_physical.effect_params + report->index;
1221 io->Information = sizeof(*report) + 1;
1222 if (packet->reportBufferLen < io->Information)
1223 io->Status = STATUS_BUFFER_TOO_SMALL;
1224 else
1226 params->periodic.magnitude = report->magnitude;
1227 params->periodic.offset = report->offset;
1228 params->periodic.phase = report->phase;
1229 params->periodic.period = report->period;
1231 io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
1234 else if (packet->reportId == physical->set_envelope_report)
1236 struct pid_set_envelope *report = (struct pid_set_envelope *)(packet->reportBuffer + 1);
1237 struct effect_params *params = iface->hid_physical.effect_params + report->index;
1239 io->Information = sizeof(*report) + 1;
1240 if (packet->reportBufferLen < io->Information)
1241 io->Status = STATUS_BUFFER_TOO_SMALL;
1242 else
1244 params->envelope.attack_level = report->attack_level;
1245 params->envelope.fade_level = report->fade_level;
1246 params->envelope.attack_time = report->attack_time;
1247 params->envelope.fade_time = report->fade_time;
1249 io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
1252 else if (packet->reportId == physical->set_condition_report)
1254 struct pid_set_condition *report = (struct pid_set_condition *)(packet->reportBuffer + 1);
1255 struct effect_params *params = iface->hid_physical.effect_params + report->index;
1256 struct effect_condition *condition;
1257 UINT index;
1259 io->Information = sizeof(*report) + 1;
1260 if (packet->reportBufferLen < io->Information)
1261 io->Status = STATUS_BUFFER_TOO_SMALL;
1262 else if ((index = report->condition_index) >= ARRAY_SIZE(params->condition))
1263 io->Status = STATUS_INVALID_PARAMETER;
1264 else
1266 if (params->condition_count <= index) params->condition_count = index + 1;
1267 condition = params->condition + index;
1268 condition->center_point_offset = report->center_point_offset;
1269 condition->positive_coefficient = report->positive_coefficient;
1270 condition->negative_coefficient = report->negative_coefficient;
1271 condition->positive_saturation = report->positive_saturation;
1272 condition->negative_saturation = report->negative_saturation;
1273 condition->dead_band = report->dead_band;
1275 io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
1278 else if (packet->reportId == physical->set_constant_force_report)
1280 struct pid_set_constant_force *report = (struct pid_set_constant_force *)(packet->reportBuffer + 1);
1281 struct effect_params *params = iface->hid_physical.effect_params + report->index;
1283 io->Information = sizeof(*report) + 1;
1284 if (packet->reportBufferLen < io->Information)
1285 io->Status = STATUS_BUFFER_TOO_SMALL;
1286 else
1288 params->constant_force.magnitude = report->magnitude;
1290 io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
1293 else if (packet->reportId == physical->set_ramp_force_report)
1295 struct pid_set_ramp_force *report = (struct pid_set_ramp_force *)(packet->reportBuffer + 1);
1296 struct effect_params *params = iface->hid_physical.effect_params + report->index;
1298 io->Information = sizeof(*report) + 1;
1299 if (packet->reportBufferLen < io->Information)
1300 io->Status = STATUS_BUFFER_TOO_SMALL;
1301 else
1303 params->ramp_force.ramp_start = report->ramp_start;
1304 params->ramp_force.ramp_end = report->ramp_end;
1306 io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
1309 else
1311 io->Information = 0;
1312 io->Status = STATUS_NOT_IMPLEMENTED;
1316 static void hid_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
1318 struct hid_haptics *haptics = &iface->hid_haptics;
1320 if (packet->reportId == haptics->features_report)
1322 struct hid_haptics_features *features = (struct hid_haptics_features *)(packet->reportBuffer + 1);
1324 io->Information = sizeof(*features) + 1;
1325 assert(packet->reportBufferLen == io->Information);
1327 *features = haptics->features;
1328 io->Status = STATUS_SUCCESS;
1330 else
1332 io->Information = 0;
1333 io->Status = STATUS_NOT_IMPLEMENTED;
1337 static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
1339 struct hid_haptics *haptics = &iface->hid_haptics;
1341 if (packet->reportId == haptics->features_report)
1343 struct hid_haptics_features *features = (struct hid_haptics_features *)(packet->reportBuffer + 1);
1345 io->Information = sizeof(*features) + 1;
1346 assert(packet->reportBufferLen == io->Information);
1348 haptics->features.rumble.cutoff_time_ms = features->rumble.cutoff_time_ms;
1349 haptics->features.buzz.cutoff_time_ms = features->buzz.cutoff_time_ms;
1350 haptics->features.left.cutoff_time_ms = features->left.cutoff_time_ms;
1351 haptics->features.right.cutoff_time_ms = features->right.cutoff_time_ms;
1352 io->Status = STATUS_SUCCESS;
1354 else
1356 io->Information = 0;
1357 io->Status = STATUS_NOT_IMPLEMENTED;
1361 static const struct raw_device_vtbl raw_device_vtbl =
1363 hid_device_destroy,
1364 hid_device_start,
1365 hid_device_stop,
1366 hid_device_get_report_descriptor,
1367 hid_device_set_output_report,
1368 hid_device_get_feature_report,
1369 hid_device_set_feature_report,
1372 void *hid_device_create(const struct hid_device_vtbl *vtbl, SIZE_T size)
1374 struct unix_device *impl;
1376 if (!(impl = raw_device_create(&raw_device_vtbl, size))) return NULL;
1377 impl->hid_vtbl = vtbl;
1379 return impl;
1382 #ifdef WORDS_BIGENDIAN
1383 # define LE_ULONG(x) RtlUlongByteSwap((ULONG)(x))
1384 #else
1385 # define LE_ULONG(x) ((ULONG)(x))
1386 #endif
1388 BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value)
1390 struct hid_device_state *state = &iface->hid_device_state;
1391 ULONG offset = state->abs_axis_start + index * 4;
1392 if (index >= state->abs_axis_count) return FALSE;
1393 *(ULONG *)(state->report_buf + offset) = LE_ULONG(value);
1394 return TRUE;
1397 BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value)
1399 struct hid_device_state *state = &iface->hid_device_state;
1400 ULONG offset = state->rel_axis_start + index * 4;
1401 if (index >= state->rel_axis_count) return FALSE;
1402 *(ULONG *)(state->report_buf + offset) = LE_ULONG(value);
1403 return TRUE;
1406 BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set)
1408 struct hid_device_state *state = &iface->hid_device_state;
1409 ULONG offset = state->button_start + (index / 8);
1410 BYTE mask = (1 << (index % 8));
1411 if (index >= state->button_count) return FALSE;
1412 if (is_set) state->report_buf[offset] |= mask;
1413 else state->report_buf[offset] &= ~mask;
1414 return TRUE;
1417 /* hatswitch x / y vs value:
1418 * -1 x +1
1419 * +-------->
1420 * -1 | 8 1 2
1421 * y | 7 0 3
1422 * +1 | 6 5 4
1425 static void hatswitch_decompose(BYTE value, ULONG index, LONG *x, LONG *y)
1427 value = (index % 2) ? (value >> 4) : (value & 0x0f);
1428 *x = *y = 0;
1429 if (value == 8 || value == 1 || value == 2) *y = -1;
1430 if (value == 6 || value == 5 || value == 4) *y = +1;
1431 if (value == 8 || value == 7 || value == 6) *x = -1;
1432 if (value == 2 || value == 3 || value == 4) *x = +1;
1435 static void hatswitch_compose(LONG x, LONG y, BYTE *value, ULONG index)
1437 BYTE new_value = 0;
1438 if (x == 0 && y == 0) new_value = 0;
1439 else if (x == 0 && y < 0) new_value = 1;
1440 else if (x > 0 && y < 0) new_value = 2;
1441 else if (x > 0 && y == 0) new_value = 3;
1442 else if (x > 0 && y > 0) new_value = 4;
1443 else if (x == 0 && y > 0) new_value = 5;
1444 else if (x < 0 && y > 0) new_value = 6;
1445 else if (x < 0 && y == 0) new_value = 7;
1446 else if (x < 0 && y < 0) new_value = 8;
1448 if (index % 2)
1450 *value &= 0xf;
1451 *value |= new_value << 4;
1453 else
1455 *value &= 0xf0;
1456 *value |= new_value;
1460 BOOL hid_device_set_hatswitch_x(struct unix_device *iface, ULONG index, LONG new_x)
1462 struct hid_device_state *state = &iface->hid_device_state;
1463 ULONG offset = state->hatswitch_start + index / 2;
1464 LONG x, y;
1465 if (index > state->hatswitch_count) return FALSE;
1466 hatswitch_decompose(state->report_buf[offset], index, &x, &y);
1467 hatswitch_compose(new_x, y, &state->report_buf[offset], index);
1468 return TRUE;
1471 BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new_y)
1473 struct hid_device_state *state = &iface->hid_device_state;
1474 ULONG offset = state->hatswitch_start + index / 2;
1475 LONG x, y;
1476 if (index > state->hatswitch_count) return FALSE;
1477 hatswitch_decompose(state->report_buf[offset], index, &x, &y);
1478 hatswitch_compose(x, new_y, &state->report_buf[offset], index);
1479 return TRUE;
1482 BOOL hid_device_move_hatswitch(struct unix_device *iface, ULONG index, LONG x, LONG y)
1484 struct hid_device_state *state = &iface->hid_device_state;
1485 ULONG offset = state->hatswitch_start + index / 2;
1486 LONG old_x, old_y;
1487 if (index > state->hatswitch_count) return FALSE;
1488 hatswitch_decompose(state->report_buf[offset], index, &old_x, &old_y);
1489 hatswitch_compose(old_x + x, old_y + y, &state->report_buf[offset], index);
1490 return TRUE;
1493 BOOL hid_device_sync_report(struct unix_device *iface)
1495 BOOL dropped;
1497 if (!(dropped = iface->hid_device_state.dropped))
1498 memcpy(iface->hid_device_state.last_report_buf, iface->hid_device_state.report_buf,
1499 iface->hid_device_state.report_len);
1500 else
1501 memcpy(iface->hid_device_state.report_buf, iface->hid_device_state.last_report_buf,
1502 iface->hid_device_state.report_len);
1503 iface->hid_device_state.dropped = FALSE;
1505 return !dropped;
1508 void hid_device_drop_report(struct unix_device *iface)
1510 iface->hid_device_state.dropped = TRUE;
1513 void hid_device_set_effect_state(struct unix_device *iface, BYTE index, BYTE flags)
1515 struct hid_effect_state *state = &iface->hid_physical.effect_state;
1516 struct pid_effect_state *report = (struct pid_effect_state *)(state->report_buf + 1);
1517 report->index = index;
1518 report->flags = flags;