winebus.sys: Handle feature and output reports in hid_device.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
777a8fbda8
commit
78f67d5c08
|
@ -128,7 +128,6 @@ struct sdl_device
|
|||
DWORD effect_support;
|
||||
SDL_Haptic *sdl_haptic;
|
||||
int haptic_effect_id;
|
||||
BYTE vendor_rumble_report_id;
|
||||
};
|
||||
|
||||
static inline struct sdl_device *impl_from_unix_device(struct unix_device *iface)
|
||||
|
@ -187,7 +186,7 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
|||
|
||||
if (impl->effect_support & EFFECT_SUPPORT_HAPTICS)
|
||||
{
|
||||
if (!hid_device_add_haptics(&impl->unix_device, &impl->vendor_rumble_report_id))
|
||||
if (!hid_device_add_haptics(&impl->unix_device))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -348,36 +347,28 @@ static void sdl_device_stop(struct unix_device *iface)
|
|||
pthread_mutex_unlock(&sdl_cs);
|
||||
}
|
||||
|
||||
static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
NTSTATUS sdl_device_haptics_start(struct unix_device *iface, DWORD duration_ms,
|
||||
USHORT rumble_intensity, USHORT buzz_intensity)
|
||||
{
|
||||
struct sdl_device *impl = impl_from_unix_device(iface);
|
||||
SDL_HapticEffect effect;
|
||||
|
||||
if (packet->reportId == impl->vendor_rumble_report_id)
|
||||
{
|
||||
WORD left = packet->reportBuffer[2] * 128;
|
||||
WORD right = packet->reportBuffer[3] * 128;
|
||||
TRACE("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u.\n", iface, duration_ms,
|
||||
rumble_intensity, buzz_intensity);
|
||||
|
||||
pSDL_memset(&effect, 0, sizeof(SDL_HapticEffect));
|
||||
effect.type = SDL_HAPTIC_LEFTRIGHT;
|
||||
effect.leftright.length = -1;
|
||||
effect.leftright.large_magnitude = left;
|
||||
effect.leftright.small_magnitude = right;
|
||||
if (!(impl->effect_support & EFFECT_SUPPORT_HAPTICS)) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
io->Information = packet->reportBufferLen;
|
||||
io->Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
return;
|
||||
}
|
||||
memset(&effect, 0, sizeof(SDL_HapticEffect));
|
||||
effect.type = SDL_HAPTIC_LEFTRIGHT;
|
||||
effect.leftright.length = duration_ms;
|
||||
effect.leftright.large_magnitude = rumble_intensity;
|
||||
effect.leftright.small_magnitude = buzz_intensity;
|
||||
|
||||
if (impl->sdl_haptic) pSDL_HapticStopAll(impl->sdl_haptic);
|
||||
if (impl->effect_support & WINE_SDL_JOYSTICK_RUMBLE)
|
||||
pSDL_JoystickRumble(impl->sdl_joystick, 0, 0, 0);
|
||||
if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude) return;
|
||||
if (!effect.leftright.large_magnitude && !effect.leftright.small_magnitude)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
if (impl->effect_support & SDL_HAPTIC_LEFTRIGHT)
|
||||
{
|
||||
|
@ -397,18 +388,8 @@ static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
|
|||
pSDL_JoystickRumble(impl->sdl_joystick, effect.leftright.large_magnitude,
|
||||
effect.leftright.small_magnitude, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void sdl_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void sdl_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl sdl_device_vtbl =
|
||||
|
@ -416,9 +397,7 @@ static const struct hid_device_vtbl sdl_device_vtbl =
|
|||
sdl_device_destroy,
|
||||
sdl_device_start,
|
||||
sdl_device_stop,
|
||||
sdl_device_set_output_report,
|
||||
sdl_device_get_feature_report,
|
||||
sdl_device_set_feature_report,
|
||||
sdl_device_haptics_start,
|
||||
};
|
||||
|
||||
static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event)
|
||||
|
|
|
@ -734,22 +734,13 @@ static void lnxev_device_read_report(struct unix_device *iface)
|
|||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
}
|
||||
|
||||
static void lnxev_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
static NTSTATUS lnxev_device_haptics_start(struct unix_device *iface, DWORD duration_ms,
|
||||
USHORT rumble_intensity, USHORT buzz_intensity)
|
||||
{
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
FIXME("iface %p, duration_ms %u, rumble_intensity %u, buzz_intensity %u stub!\n", iface,
|
||||
duration_ms, rumble_intensity, buzz_intensity);
|
||||
|
||||
static void lnxev_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void lnxev_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl lnxev_device_vtbl =
|
||||
|
@ -757,9 +748,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl =
|
|||
lnxev_device_destroy,
|
||||
lnxev_device_start,
|
||||
lnxev_device_stop,
|
||||
lnxev_device_set_output_report,
|
||||
lnxev_device_get_feature_report,
|
||||
lnxev_device_set_feature_report,
|
||||
lnxev_device_haptics_start,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id)
|
||||
BOOL hid_device_add_haptics(struct unix_device *iface)
|
||||
{
|
||||
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
||||
const BYTE report_id = ++desc->next_report_id[HidP_Output];
|
||||
|
@ -342,7 +342,7 @@ BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id)
|
|||
END_COLLECTION,
|
||||
};
|
||||
|
||||
*id = report_id;
|
||||
iface->hid_haptics.vendor_report = report_id;
|
||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||
}
|
||||
|
||||
|
@ -377,17 +377,32 @@ NTSTATUS hid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffe
|
|||
|
||||
static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
return iface->hid_vtbl->set_output_report(iface, packet, io);
|
||||
struct hid_haptics *haptics = &iface->hid_haptics;
|
||||
if (packet->reportId == haptics->vendor_report)
|
||||
{
|
||||
WORD left = packet->reportBuffer[2] * 128;
|
||||
WORD right = packet->reportBuffer[3] * 128;
|
||||
|
||||
io->Information = packet->reportBufferLen;
|
||||
io->Status = iface->hid_vtbl->haptics_start(iface, -1, left, right);
|
||||
}
|
||||
else
|
||||
{
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
static void hid_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
return iface->hid_vtbl->get_feature_report(iface, packet, io);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
return iface->hid_vtbl->set_feature_report(iface, packet, io);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static const struct raw_device_vtbl raw_device_vtbl =
|
||||
|
|
|
@ -45,9 +45,8 @@ struct hid_device_vtbl
|
|||
void (*destroy)(struct unix_device *iface);
|
||||
NTSTATUS (*start)(struct unix_device *iface);
|
||||
void (*stop)(struct unix_device *iface);
|
||||
void (*set_output_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
|
||||
void (*get_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
|
||||
void (*set_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
|
||||
NTSTATUS (*haptics_start)(struct unix_device *iface, DWORD duration_ms,
|
||||
USHORT rumble_intensity, USHORT buzz_intensity);
|
||||
};
|
||||
|
||||
struct hid_report_descriptor
|
||||
|
@ -58,6 +57,11 @@ struct hid_report_descriptor
|
|||
BYTE next_report_id[3];
|
||||
};
|
||||
|
||||
struct hid_haptics
|
||||
{
|
||||
BYTE vendor_report;
|
||||
};
|
||||
|
||||
struct hid_device_state
|
||||
{
|
||||
ULONG bit_size;
|
||||
|
@ -85,6 +89,7 @@ struct unix_device
|
|||
const struct hid_device_vtbl *hid_vtbl;
|
||||
struct hid_report_descriptor hid_report_descriptor;
|
||||
struct hid_device_state hid_device_state;
|
||||
struct hid_haptics hid_haptics;
|
||||
};
|
||||
|
||||
extern void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
|
||||
|
@ -121,7 +126,7 @@ extern BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count) DECLS
|
|||
extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page,
|
||||
const USAGE *usages, BOOL rel, LONG min, LONG max) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL hid_device_add_haptics(struct unix_device *iface, BYTE *id) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
|
||||
#include "unix_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
|
||||
|
||||
BOOL is_xbox_gamepad(WORD vid, WORD pid)
|
||||
{
|
||||
if (vid != 0x045e) return FALSE;
|
||||
|
@ -84,25 +82,10 @@ static void mouse_stop(struct unix_device *iface)
|
|||
{
|
||||
}
|
||||
|
||||
static void mouse_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
static NTSTATUS mouse_haptics_start(struct unix_device *iface, DWORD duration,
|
||||
USHORT rumble_intensity, USHORT buzz_intensity)
|
||||
{
|
||||
FIXME("id %u, stub!\n", packet->reportId);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void mouse_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
FIXME("id %u, stub!\n", packet->reportId);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void mouse_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
FIXME("id %u, stub!\n", packet->reportId);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl mouse_vtbl =
|
||||
|
@ -110,9 +93,7 @@ static const struct hid_device_vtbl mouse_vtbl =
|
|||
mouse_destroy,
|
||||
mouse_start,
|
||||
mouse_stop,
|
||||
mouse_set_output_report,
|
||||
mouse_get_feature_report,
|
||||
mouse_set_feature_report,
|
||||
mouse_haptics_start,
|
||||
};
|
||||
|
||||
static const struct device_desc mouse_device_desc =
|
||||
|
@ -158,25 +139,10 @@ static void keyboard_stop(struct unix_device *iface)
|
|||
{
|
||||
}
|
||||
|
||||
static void keyboard_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
static NTSTATUS keyboard_haptics_start(struct unix_device *iface, DWORD duration,
|
||||
USHORT rumble_intensity, USHORT buzz_intensity)
|
||||
{
|
||||
FIXME("id %u, stub!\n", packet->reportId);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void keyboard_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
FIXME("id %u, stub!\n", packet->reportId);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void keyboard_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
|
||||
{
|
||||
FIXME("id %u, stub!\n", packet->reportId);
|
||||
io->Information = 0;
|
||||
io->Status = STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static const struct hid_device_vtbl keyboard_vtbl =
|
||||
|
@ -184,9 +150,7 @@ static const struct hid_device_vtbl keyboard_vtbl =
|
|||
keyboard_destroy,
|
||||
keyboard_start,
|
||||
keyboard_stop,
|
||||
keyboard_set_output_report,
|
||||
keyboard_get_feature_report,
|
||||
keyboard_set_feature_report,
|
||||
keyboard_haptics_start,
|
||||
};
|
||||
|
||||
static const struct device_desc keyboard_device_desc =
|
||||
|
|
Loading…
Reference in New Issue