winebus.sys: Add haptics rumble support for UDEV lnxev devices.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e42f11d7a2
commit
a27708dc9b
|
@ -126,6 +126,8 @@ struct lnxev_device
|
||||||
BYTE rel_map[HID_REL_MAX];
|
BYTE rel_map[HID_REL_MAX];
|
||||||
BYTE hat_map[8];
|
BYTE hat_map[8];
|
||||||
BYTE button_map[KEY_MAX];
|
BYTE button_map[KEY_MAX];
|
||||||
|
|
||||||
|
int haptic_effect_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct base_device *impl_from_unix_device(struct unix_device *iface)
|
static inline struct base_device *impl_from_unix_device(struct unix_device *iface)
|
||||||
|
@ -372,6 +374,8 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
||||||
struct input_absinfo abs_info[HID_ABS_MAX];
|
struct input_absinfo abs_info[HID_ABS_MAX];
|
||||||
BYTE absbits[(ABS_MAX+7)/8];
|
BYTE absbits[(ABS_MAX+7)/8];
|
||||||
BYTE relbits[(REL_MAX+7)/8];
|
BYTE relbits[(REL_MAX+7)/8];
|
||||||
|
BYTE ffbits[(FF_MAX+7)/8];
|
||||||
|
struct ff_effect effect;
|
||||||
USAGE_AND_PAGE usage;
|
USAGE_AND_PAGE usage;
|
||||||
INT i, button_count, abs_count, rel_count, hat_count;
|
INT i, button_count, abs_count, rel_count, hat_count;
|
||||||
const BYTE *device_usage = what_am_I(dev);
|
const BYTE *device_usage = what_am_I(dev);
|
||||||
|
@ -387,6 +391,11 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
||||||
WARN("ioctl(EVIOCGBIT, EV_ABS) failed: %d %s\n", errno, strerror(errno));
|
WARN("ioctl(EVIOCGBIT, EV_ABS) failed: %d %s\n", errno, strerror(errno));
|
||||||
memset(absbits, 0, sizeof(absbits));
|
memset(absbits, 0, sizeof(absbits));
|
||||||
}
|
}
|
||||||
|
if (ioctl(impl->base.device_fd, EVIOCGBIT(EV_FF, sizeof(ffbits)), ffbits) == -1)
|
||||||
|
{
|
||||||
|
WARN("ioctl(EVIOCGBIT, EV_FF) failed: %d %s\n", errno, strerror(errno));
|
||||||
|
memset(ffbits, 0, sizeof(ffbits));
|
||||||
|
}
|
||||||
|
|
||||||
if (!hid_device_begin_report_descriptor(iface, device_usage[0], device_usage[1]))
|
if (!hid_device_begin_report_descriptor(iface, device_usage[0], device_usage[1]))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
@ -443,6 +452,23 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
||||||
if (!hid_device_end_input_report(iface))
|
if (!hid_device_end_input_report(iface))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
impl->haptic_effect_id = -1;
|
||||||
|
if (test_bit(ffbits, FF_RUMBLE))
|
||||||
|
{
|
||||||
|
effect.id = -1;
|
||||||
|
effect.type = FF_RUMBLE;
|
||||||
|
effect.replay.length = 0;
|
||||||
|
effect.u.rumble.strong_magnitude = 0;
|
||||||
|
effect.u.rumble.weak_magnitude = 0;
|
||||||
|
|
||||||
|
if (ioctl(impl->base.device_fd, EVIOCSFF, &effect) == -1)
|
||||||
|
WARN("couldn't allocate rumble effect for haptics: %d %s\n", errno, strerror(errno));
|
||||||
|
else if (!hid_device_add_haptics(iface))
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
impl->haptic_effect_id = effect.id;
|
||||||
|
}
|
||||||
|
|
||||||
if (!hid_device_end_report_descriptor(iface))
|
if (!hid_device_end_report_descriptor(iface))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
@ -737,10 +763,42 @@ static void lnxev_device_read_report(struct unix_device *iface)
|
||||||
static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, DWORD duration_ms,
|
static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, DWORD duration_ms,
|
||||||
USHORT rumble_intensity, USHORT buzz_intensity)
|
USHORT rumble_intensity, USHORT buzz_intensity)
|
||||||
{
|
{
|
||||||
FIXME("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u stub!\n", iface,
|
struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
|
||||||
|
struct ff_effect effect =
|
||||||
|
{
|
||||||
|
.id = impl->haptic_effect_id,
|
||||||
|
.type = FF_RUMBLE,
|
||||||
|
};
|
||||||
|
struct input_event event;
|
||||||
|
|
||||||
|
TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u stub!\n", iface,
|
||||||
duration_ms, rumble_intensity, buzz_intensity);
|
duration_ms, rumble_intensity, buzz_intensity);
|
||||||
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
effect.replay.length = duration_ms;
|
||||||
|
effect.u.rumble.strong_magnitude = rumble_intensity;
|
||||||
|
effect.u.rumble.weak_magnitude = buzz_intensity;
|
||||||
|
|
||||||
|
if (ioctl(impl->base.device_fd, EVIOCSFF, &effect) == -1)
|
||||||
|
{
|
||||||
|
effect.id = -1;
|
||||||
|
if (ioctl(impl->base.device_fd, EVIOCSFF, &effect) == 1)
|
||||||
|
{
|
||||||
|
WARN("couldn't re-allocate rumble effect for haptics: %d %s\n", errno, strerror(errno));
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
impl->haptic_effect_id = effect.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.type = EV_FF;
|
||||||
|
event.code = effect.id;
|
||||||
|
event.value = 1;
|
||||||
|
if (write(impl->base.device_fd, &event, sizeof(event)) == -1)
|
||||||
|
{
|
||||||
|
WARN("couldn't start haptics rumble effect: %d %s\n", errno, strerror(errno));
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct hid_device_vtbl lnxev_device_vtbl =
|
static const struct hid_device_vtbl lnxev_device_vtbl =
|
||||||
|
|
Loading…
Reference in New Issue