diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index beb2ebe8ad9..29d5debcfe2 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -475,6 +475,12 @@ struct pid_set_ramp_force INT16 ramp_start; INT16 ramp_end; }; + +struct pid_effect_state +{ + BYTE flags; + BYTE index; +}; #include "poppack.h" static BOOL hid_descriptor_add_set_periodic(struct unix_device *iface) @@ -883,6 +889,33 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co UNIT(1, 0), /* None */ END_COLLECTION, }; + + const BYTE effect_state_report = ++desc->next_report_id[HidP_Input]; + const BYTE effect_state_template[] = + { + /* Report effect state */ + USAGE(1, PID_USAGE_STATE_REPORT), + COLLECTION(1, Logical), + REPORT_ID(1, effect_state_report), + + USAGE(1, PID_USAGE_DEVICE_PAUSED), + USAGE(1, PID_USAGE_ACTUATORS_ENABLED), + USAGE(1, PID_USAGE_EFFECT_PLAYING), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_SIZE(1, 1), + REPORT_COUNT(1, 8), + INPUT(1, Data|Var|Abs), + + USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 0x7f), + REPORT_SIZE(1, 8), + REPORT_COUNT(1, 1), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + }; + struct hid_effect_state *effect_state = &iface->hid_physical.effect_state; BOOL periodic = FALSE; BOOL envelope = FALSE; BOOL condition = FALSE; @@ -953,6 +986,9 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co if (ramp_force && !hid_descriptor_add_set_ramp_force(iface)) return FALSE; + if (!hid_report_descriptor_append(desc, effect_state_template, sizeof(effect_state_template))) + return FALSE; + /* HID nary collection indexes start at 1 */ memcpy(iface->hid_physical.effect_types + 1, usages, count * sizeof(*usages)); @@ -960,6 +996,12 @@ BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT co iface->hid_physical.device_gain_report = device_gain_report; iface->hid_physical.effect_control_report = effect_control_report; iface->hid_physical.effect_update_report = effect_update_report; + + effect_state->id = effect_state_report; + effect_state->report_len = sizeof(struct pid_effect_state) + 1; + if (!(effect_state->report_buf = calloc(1, effect_state->report_len))) return FALSE; + effect_state->report_buf[0] = effect_state->id; + return TRUE; } diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 10784652a2b..564fec9fc3a 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -151,6 +151,22 @@ struct hid_haptics BYTE waveform_report; }; +/* must match the order and number of usages in the + * PID_USAGE_STATE_REPORT report */ +enum effect_state_flags +{ + EFFECT_STATE_DEVICE_PAUSED = 0x01, + EFFECT_STATE_ACTUATORS_ENABLED = 0x02, + EFFECT_STATE_EFFECT_PLAYING = 0x04, +}; + +struct hid_effect_state +{ + USHORT report_len; + BYTE *report_buf; + BYTE id; +}; + struct hid_physical { USAGE effect_types[32]; @@ -165,6 +181,8 @@ struct hid_physical BYTE set_condition_report; BYTE set_constant_force_report; BYTE set_ramp_force_report; + + struct hid_effect_state effect_state; }; struct hid_device_state