winebus.sys: Move device vtable to the struct unix_device side.

And name the callbacks a bit more consistently.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-09-03 09:30:49 +02:00 committed by Alexandre Julliard
parent 08f943b595
commit 4366cba6e6
8 changed files with 390 additions and 172 deletions

View file

@ -29,24 +29,10 @@
typedef int(*enum_func)(DEVICE_OBJECT *device, void *context); typedef int(*enum_func)(DEVICE_OBJECT *device, void *context);
/* Native device function table */
typedef struct
{
void (*free_device)(DEVICE_OBJECT *device);
int (*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev);
NTSTATUS (*start_device)(DEVICE_OBJECT *device);
NTSTATUS (*get_reportdescriptor)(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length);
NTSTATUS (*get_string)(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length);
void (*set_output_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
void (*get_feature_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
void (*set_feature_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
} platform_vtbl;
struct unix_device *get_unix_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; struct unix_device *get_unix_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
/* HID Plug and Play Bus */ /* HID Plug and Play Bus */
DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vtbl *vtbl, DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, struct unix_device *unix_device) DECLSPEC_HIDDEN;
struct unix_device *unix_device) DECLSPEC_HIDDEN;
DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev) DECLSPEC_HIDDEN; DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev) DECLSPEC_HIDDEN;
void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLSPEC_HIDDEN; void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLSPEC_HIDDEN;
DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function, void *context) DECLSPEC_HIDDEN; DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function, void *context) DECLSPEC_HIDDEN;
@ -56,6 +42,3 @@ BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
extern HANDLE driver_key DECLSPEC_HIDDEN; extern HANDLE driver_key DECLSPEC_HIDDEN;
extern DEVICE_OBJECT *bus_pdo DECLSPEC_HIDDEN; extern DEVICE_OBJECT *bus_pdo DECLSPEC_HIDDEN;
extern const platform_vtbl mouse_vtbl DECLSPEC_HIDDEN;
extern const platform_vtbl keyboard_vtbl DECLSPEC_HIDDEN;

View file

@ -114,11 +114,6 @@ static inline struct platform_private *impl_from_unix_device(struct unix_device
return CONTAINING_RECORD(iface, struct platform_private, unix_device); return CONTAINING_RECORD(iface, struct platform_private, unix_device);
} }
static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
{
return impl_from_unix_device(get_unix_device(device));
}
static void CFStringToWSTR(CFStringRef cstr, LPWSTR wstr, int length) static void CFStringToWSTR(CFStringRef cstr, LPWSTR wstr, int length)
{ {
int len = min(CFStringGetLength(cstr), length-1); int len = min(CFStringGetLength(cstr), length-1);
@ -142,26 +137,26 @@ static void handle_IOHIDDeviceIOHIDReportCallback(void *context,
process_hid_report(device, report, report_length); process_hid_report(device, report, report_length);
} }
static void free_device(DEVICE_OBJECT *device) static void iohid_device_destroy(struct unix_device *iface)
{ {
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
HeapFree(GetProcessHeap(), 0, private); HeapFree(GetProcessHeap(), 0, private);
} }
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) static int iohid_device_compare(struct unix_device *iface, void *context)
{ {
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
IOHIDDeviceRef dev2 = (IOHIDDeviceRef)platform_dev; IOHIDDeviceRef dev2 = (IOHIDDeviceRef)context;
if (private->device != dev2) if (private->device != dev2)
return 1; return 1;
else else
return 0; return 0;
} }
static NTSTATUS start_device(DEVICE_OBJECT *device) static NTSTATUS iohid_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
{ {
DWORD length; DWORD length;
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
CFNumberRef num; CFNumberRef num;
num = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDMaxInputReportSizeKey)); num = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDMaxInputReportSizeKey));
@ -172,9 +167,10 @@ static NTSTATUS start_device(DEVICE_OBJECT *device)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) static NTSTATUS iohid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
DWORD length, DWORD *out_length)
{ {
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
CFDataRef data = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDReportDescriptorKey)); CFDataRef data = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDReportDescriptorKey));
int data_length = CFDataGetLength(data); int data_length = CFDataGetLength(data);
const UInt8 *ptr; const UInt8 *ptr;
@ -188,9 +184,9 @@ static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length) static NTSTATUS iohid_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
{ {
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
CFStringRef str; CFStringRef str;
switch (index) switch (index)
{ {
@ -223,10 +219,10 @@ static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DW
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void iohid_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
IOReturn result; IOReturn result;
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
result = IOHIDDeviceSetReport(private->device, kIOHIDReportTypeOutput, packet->reportId, result = IOHIDDeviceSetReport(private->device, kIOHIDReportTypeOutput, packet->reportId,
packet->reportBuffer, packet->reportBufferLen); packet->reportBuffer, packet->reportBufferLen);
if (result == kIOReturnSuccess) if (result == kIOReturnSuccess)
@ -241,11 +237,11 @@ static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO
} }
} }
static void get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void iohid_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
IOReturn ret; IOReturn ret;
CFIndex report_length = packet->reportBufferLen; CFIndex report_length = packet->reportBufferLen;
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
ret = IOHIDDeviceGetReport(private->device, kIOHIDReportTypeFeature, packet->reportId, ret = IOHIDDeviceGetReport(private->device, kIOHIDReportTypeFeature, packet->reportId,
packet->reportBuffer, &report_length); packet->reportBuffer, &report_length);
@ -261,10 +257,10 @@ static void get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, I
} }
} }
static void set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void iohid_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
IOReturn result; IOReturn result;
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
result = IOHIDDeviceSetReport(private->device, kIOHIDReportTypeFeature, packet->reportId, result = IOHIDDeviceSetReport(private->device, kIOHIDReportTypeFeature, packet->reportId,
packet->reportBuffer, packet->reportBufferLen); packet->reportBuffer, packet->reportBufferLen);
@ -280,16 +276,16 @@ static void set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, I
} }
} }
static const platform_vtbl iohid_vtbl = static const struct unix_device_vtbl iohid_device_vtbl =
{ {
free_device, iohid_device_destroy,
compare_platform_device, iohid_device_compare,
start_device, iohid_device_start,
get_reportdescriptor, iohid_device_get_report_descriptor,
get_string, iohid_device_get_string,
set_output_report, iohid_device_set_output_report,
get_feature_report, iohid_device_get_feature_report,
set_feature_report, iohid_device_set_feature_report,
}; };
static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef IOHIDDevice) static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef IOHIDDevice)
@ -367,8 +363,9 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private)))) if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private))))
return; return;
private->unix_device.vtbl = &iohid_device_vtbl;
device = bus_create_hid_device(&desc, &iohid_vtbl, &private->unix_device); device = bus_create_hid_device(&desc, &private->unix_device);
if (!device) HeapFree(GetProcessHeap(), 0, private); if (!device) HeapFree(GetProcessHeap(), 0, private);
else else
{ {

View file

@ -478,9 +478,9 @@ failed:
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
static void free_device(DEVICE_OBJECT *device) static void sdl_device_destroy(struct unix_device *iface)
{ {
struct platform_private *ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
pSDL_JoystickClose(ext->sdl_joystick); pSDL_JoystickClose(ext->sdl_joystick);
if (ext->sdl_controller) if (ext->sdl_controller)
@ -491,21 +491,22 @@ static void free_device(DEVICE_OBJECT *device)
HeapFree(GetProcessHeap(), 0, ext); HeapFree(GetProcessHeap(), 0, ext);
} }
static int compare_platform_device(DEVICE_OBJECT *device, void *context) static int sdl_device_compare(struct unix_device *iface, void *context)
{ {
return impl_from_DEVICE_OBJECT(device)->id - PtrToUlong(context); return impl_from_unix_device(iface)->id - PtrToUlong(context);
} }
static NTSTATUS start_device(DEVICE_OBJECT *device) static NTSTATUS sdl_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
{ {
struct platform_private *ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
if (ext->sdl_controller) return build_mapped_report_descriptor(ext); if (ext->sdl_controller) return build_mapped_report_descriptor(ext);
return build_report_descriptor(ext); return build_report_descriptor(ext);
} }
static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) static NTSTATUS sdl_device_get_reportdescriptor(struct unix_device *iface, BYTE *buffer,
DWORD length, DWORD *out_length)
{ {
struct platform_private *ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
*out_length = ext->desc.size; *out_length = ext->desc.size;
if (length < ext->desc.size) return STATUS_BUFFER_TOO_SMALL; if (length < ext->desc.size) return STATUS_BUFFER_TOO_SMALL;
@ -514,9 +515,9 @@ static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length) static NTSTATUS sdl_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
{ {
struct platform_private *ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
const char* str = NULL; const char* str = NULL;
switch (index) switch (index)
@ -545,9 +546,9 @@ static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DW
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
struct platform_private *ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
if (ext->sdl_haptic && packet->reportId == 0) if (ext->sdl_haptic && packet->reportId == 0)
{ {
@ -592,28 +593,28 @@ static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO
} }
} }
static void get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void sdl_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static void set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void sdl_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static const platform_vtbl sdl_vtbl = static const struct unix_device_vtbl sdl_device_vtbl =
{ {
free_device, sdl_device_destroy,
compare_platform_device, sdl_device_compare,
start_device, sdl_device_start,
get_reportdescriptor, sdl_device_get_reportdescriptor,
get_string, sdl_device_get_string,
set_output_report, sdl_device_set_output_report,
get_feature_report, sdl_device_get_feature_report,
set_feature_report, sdl_device_set_feature_report,
}; };
static BOOL set_report_from_event(DEVICE_OBJECT *device, SDL_Event *event) static BOOL set_report_from_event(DEVICE_OBJECT *device, SDL_Event *event)
@ -787,9 +788,11 @@ static void sdl_add_device(unsigned int index)
TRACE("%s id %d, desc %s.\n", controller ? "controller" : "joystick", id, debugstr_device_desc(&desc)); TRACE("%s id %d, desc %s.\n", controller ? "controller" : "joystick", id, debugstr_device_desc(&desc));
if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*private)))) return; if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*private))))
return;
private->unix_device.vtbl = &sdl_device_vtbl;
device = bus_create_hid_device(&desc, &sdl_vtbl, &private->unix_device); device = bus_create_hid_device(&desc, &private->unix_device);
if (!device) HeapFree(GetProcessHeap(), 0, private); if (!device) HeapFree(GetProcessHeap(), 0, private);
else else
{ {

View file

@ -543,9 +543,9 @@ static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr)
return strdupAtoW(attr); return strdupAtoW(attr);
} }
static void hidraw_free_device(DEVICE_OBJECT *device) static void hidraw_device_destroy(struct unix_device *iface)
{ {
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
if (private->report_thread) if (private->report_thread)
{ {
@ -562,18 +562,18 @@ static void hidraw_free_device(DEVICE_OBJECT *device)
HeapFree(GetProcessHeap(), 0, private); HeapFree(GetProcessHeap(), 0, private);
} }
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) static int udev_device_compare(struct unix_device *iface, void *platform_dev)
{ {
struct udev_device *dev1 = impl_from_DEVICE_OBJECT(device)->udev_device; struct udev_device *dev1 = impl_from_unix_device(iface)->udev_device;
struct udev_device *dev2 = platform_dev; struct udev_device *dev2 = platform_dev;
return strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2)); return strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2));
} }
static DWORD CALLBACK device_report_thread(void *args); static DWORD CALLBACK device_report_thread(void *args);
static NTSTATUS hidraw_start_device(DEVICE_OBJECT *device) static NTSTATUS hidraw_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
{ {
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
if (pipe(private->control_pipe) != 0) if (pipe(private->control_pipe) != 0)
{ {
@ -593,11 +593,12 @@ static NTSTATUS hidraw_start_device(DEVICE_OBJECT *device)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS hidraw_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) static NTSTATUS hidraw_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
DWORD length, DWORD *out_length)
{ {
#ifdef HAVE_LINUX_HIDRAW_H #ifdef HAVE_LINUX_HIDRAW_H
struct hidraw_report_descriptor descriptor; struct hidraw_report_descriptor descriptor;
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
if (ioctl(private->device_fd, HIDIOCGRDESCSIZE, &descriptor.size) == -1) if (ioctl(private->device_fd, HIDIOCGRDESCSIZE, &descriptor.size) == -1)
{ {
@ -625,10 +626,10 @@ static NTSTATUS hidraw_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer,
#endif #endif
} }
static NTSTATUS hidraw_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length) static NTSTATUS hidraw_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
{ {
struct udev_device *usbdev; struct udev_device *usbdev;
struct platform_private *private = impl_from_DEVICE_OBJECT(device); struct platform_private *private = impl_from_unix_device(iface);
WCHAR *str = NULL; WCHAR *str = NULL;
usbdev = udev_device_get_parent_with_subsystem_devtype(private->udev_device, "usb", "usb_device"); usbdev = udev_device_get_parent_with_subsystem_devtype(private->udev_device, "usb", "usb_device");
@ -727,9 +728,9 @@ static DWORD CALLBACK device_report_thread(void *args)
return 0; return 0;
} }
static void hidraw_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void hidraw_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
struct platform_private* ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
ULONG length = packet->reportBufferLen; ULONG length = packet->reportBufferLen;
BYTE buffer[8192]; BYTE buffer[8192];
int count = 0; int count = 0;
@ -757,10 +758,11 @@ static void hidraw_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *pac
} }
} }
static void hidraw_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void hidraw_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet,
IO_STATUS_BLOCK *io)
{ {
#if defined(HAVE_LINUX_HIDRAW_H) && defined(HIDIOCGFEATURE) #if defined(HAVE_LINUX_HIDRAW_H) && defined(HIDIOCGFEATURE)
struct platform_private* ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
ULONG length = packet->reportBufferLen; ULONG length = packet->reportBufferLen;
BYTE buffer[8192]; BYTE buffer[8192];
int count = 0; int count = 0;
@ -792,10 +794,11 @@ static void hidraw_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *pa
#endif #endif
} }
static void hidraw_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void hidraw_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet,
IO_STATUS_BLOCK *io)
{ {
#if defined(HAVE_LINUX_HIDRAW_H) && defined(HIDIOCSFEATURE) #if defined(HAVE_LINUX_HIDRAW_H) && defined(HIDIOCSFEATURE)
struct platform_private* ext = impl_from_DEVICE_OBJECT(device); struct platform_private *ext = impl_from_unix_device(iface);
ULONG length = packet->reportBufferLen; ULONG length = packet->reportBufferLen;
BYTE buffer[8192]; BYTE buffer[8192];
int count = 0; int count = 0;
@ -827,28 +830,33 @@ static void hidraw_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *pa
#endif #endif
} }
static const platform_vtbl hidraw_vtbl = static const struct unix_device_vtbl hidraw_device_vtbl =
{ {
hidraw_free_device, hidraw_device_destroy,
compare_platform_device, udev_device_compare,
hidraw_start_device, hidraw_device_start,
hidraw_get_reportdescriptor, hidraw_device_get_report_descriptor,
hidraw_get_string, hidraw_device_get_string,
hidraw_set_output_report, hidraw_device_set_output_report,
hidraw_get_feature_report, hidraw_device_get_feature_report,
hidraw_set_feature_report, hidraw_device_set_feature_report,
}; };
#ifdef HAS_PROPER_INPUT_HEADER #ifdef HAS_PROPER_INPUT_HEADER
static inline struct wine_input_private *input_impl_from_unix_device(struct unix_device *iface)
{
return CONTAINING_RECORD(impl_from_unix_device(iface), struct wine_input_private, base);
}
static inline struct wine_input_private *input_impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) static inline struct wine_input_private *input_impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
{ {
return CONTAINING_RECORD(impl_from_DEVICE_OBJECT(device), struct wine_input_private, base); return CONTAINING_RECORD(impl_from_DEVICE_OBJECT(device), struct wine_input_private, base);
} }
static void lnxev_free_device(DEVICE_OBJECT *device) static void lnxev_device_destroy(struct unix_device *iface)
{ {
struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device); struct wine_input_private *ext = input_impl_from_unix_device(iface);
if (ext->base.report_thread) if (ext->base.report_thread)
{ {
@ -871,9 +879,9 @@ static void lnxev_free_device(DEVICE_OBJECT *device)
static DWORD CALLBACK lnxev_device_report_thread(void *args); static DWORD CALLBACK lnxev_device_report_thread(void *args);
static NTSTATUS lnxev_start_device(DEVICE_OBJECT *device) static NTSTATUS lnxev_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
{ {
struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device); struct wine_input_private *ext = input_impl_from_unix_device(iface);
NTSTATUS status; NTSTATUS status;
if ((status = build_report_descriptor(ext, ext->base.udev_device))) if ((status = build_report_descriptor(ext, ext->base.udev_device)))
@ -897,9 +905,10 @@ static NTSTATUS lnxev_start_device(DEVICE_OBJECT *device)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS lnxev_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) static NTSTATUS lnxev_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
DWORD length, DWORD *out_length)
{ {
struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device); struct wine_input_private *ext = input_impl_from_unix_device(iface);
*out_length = ext->desc.size; *out_length = ext->desc.size;
if (length < ext->desc.size) return STATUS_BUFFER_TOO_SMALL; if (length < ext->desc.size) return STATUS_BUFFER_TOO_SMALL;
@ -908,9 +917,9 @@ static NTSTATUS lnxev_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS lnxev_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length) static NTSTATUS lnxev_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
{ {
struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device); struct wine_input_private *ext = input_impl_from_unix_device(iface);
char str[255]; char str[255];
str[0] = 0; str[0] = 0;
@ -965,33 +974,34 @@ static DWORD CALLBACK lnxev_device_report_thread(void *args)
return 0; return 0;
} }
static void lnxev_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void lnxev_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static void lnxev_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void lnxev_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static void lnxev_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void lnxev_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static const platform_vtbl lnxev_vtbl = { static const struct unix_device_vtbl lnxev_device_vtbl =
lnxev_free_device, {
compare_platform_device, lnxev_device_destroy,
lnxev_start_device, udev_device_compare,
lnxev_get_reportdescriptor, lnxev_device_start,
lnxev_get_string, lnxev_device_get_report_descriptor,
lnxev_set_output_report, lnxev_device_get_string,
lnxev_get_feature_report, lnxev_device_set_output_report,
lnxev_set_feature_report, lnxev_device_get_feature_report,
lnxev_device_set_feature_report,
}; };
#endif #endif
@ -1145,7 +1155,9 @@ static void udev_add_device(struct udev_device *dev)
{ {
if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private)))) if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private))))
return; return;
device = bus_create_hid_device(&desc, &hidraw_vtbl, &private->unix_device); private->unix_device.vtbl = &hidraw_device_vtbl;
device = bus_create_hid_device(&desc, &private->unix_device);
if (!device) HeapFree(GetProcessHeap(), 0, private); if (!device) HeapFree(GetProcessHeap(), 0, private);
} }
#ifdef HAS_PROPER_INPUT_HEADER #ifdef HAS_PROPER_INPUT_HEADER
@ -1153,7 +1165,9 @@ static void udev_add_device(struct udev_device *dev)
{ {
if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wine_input_private)))) if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wine_input_private))))
return; return;
device = bus_create_hid_device(&desc, &lnxev_vtbl, &private->unix_device); private->unix_device.vtbl = &lnxev_device_vtbl;
device = bus_create_hid_device(&desc, &private->unix_device);
if (!device) HeapFree(GetProcessHeap(), 0, private); if (!device) HeapFree(GetProcessHeap(), 0, private);
} }
#endif #endif

View file

@ -121,8 +121,6 @@ struct device_extension
struct device_desc desc; struct device_desc desc;
DWORD index; DWORD index;
const platform_vtbl *vtbl;
BYTE *last_report; BYTE *last_report;
DWORD last_report_size; DWORD last_report_size;
BOOL last_report_read; BOOL last_report_read;
@ -148,6 +146,96 @@ static NTSTATUS winebus_call(unsigned int code, void *args)
return __wine_unix_call_funcs[code]( args ); return __wine_unix_call_funcs[code]( args );
} }
static void unix_device_remove(DEVICE_OBJECT *device)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
winebus_call(device_remove, ext->unix_device);
}
static int unix_device_compare(DEVICE_OBJECT *device, void *context)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
struct device_compare_params params =
{
.iface = ext->unix_device,
.context = context
};
return winebus_call(device_compare, &params);
}
static NTSTATUS unix_device_start(DEVICE_OBJECT *device)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
struct device_start_params params =
{
.iface = ext->unix_device,
.device = device
};
return winebus_call(device_start, &params);
}
static NTSTATUS unix_device_get_report_descriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
struct device_descriptor_params params =
{
.iface = ext->unix_device,
.buffer = buffer,
.length = length,
.out_length = out_length
};
return winebus_call(device_get_report_descriptor, &params);
}
static NTSTATUS unix_device_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
struct device_string_params params =
{
.iface = ext->unix_device,
.index = index,
.buffer = buffer,
.length = length,
};
return winebus_call(device_get_string, &params);
}
static void unix_device_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
struct device_report_params params =
{
.iface = ext->unix_device,
.packet = packet,
.io = io,
};
winebus_call(device_set_output_report, &params);
}
static void unix_device_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
struct device_report_params params =
{
.iface = ext->unix_device,
.packet = packet,
.io = io,
};
winebus_call(device_get_feature_report, &params);
}
static void unix_device_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
struct device_report_params params =
{
.iface = ext->unix_device,
.packet = packet,
.io = io,
};
winebus_call(device_set_feature_report, &params);
}
struct unix_device *get_unix_device(DEVICE_OBJECT *device) struct unix_device *get_unix_device(DEVICE_OBJECT *device)
{ {
struct device_extension *ext = (struct device_extension *)device->DeviceExtension; struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
@ -253,8 +341,7 @@ static void remove_pending_irps(DEVICE_OBJECT *device)
} }
} }
DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vtbl *vtbl, DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, struct unix_device *unix_device)
struct unix_device *unix_device)
{ {
static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0}; static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0};
struct device_extension *ext; struct device_extension *ext;
@ -263,7 +350,7 @@ DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vt
WCHAR dev_name[256]; WCHAR dev_name[256];
NTSTATUS status; NTSTATUS status;
TRACE("desc %s, vtbl %p, unix_device %p\n", debugstr_device_desc(desc), vtbl, unix_device); TRACE("desc %s, unix_device %p\n", debugstr_device_desc(desc), unix_device);
sprintfW(dev_name, device_name_fmtW, desc->busid, unix_device); sprintfW(dev_name, device_name_fmtW, desc->busid, unix_device);
RtlInitUnicodeString(&nameW, dev_name); RtlInitUnicodeString(&nameW, dev_name);
@ -281,7 +368,6 @@ DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vt
ext->device = device; ext->device = device;
ext->desc = *desc; ext->desc = *desc;
ext->index = get_device_index(desc); ext->index = get_device_index(desc);
ext->vtbl = vtbl;
ext->last_report = NULL; ext->last_report = NULL;
ext->last_report_size = 0; ext->last_report_size = 0;
ext->last_report_read = TRUE; ext->last_report_read = TRUE;
@ -310,7 +396,7 @@ DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev)
LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry) LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry)
{ {
if (strcmpW(ext->desc.busid, bus_id)) continue; if (strcmpW(ext->desc.busid, bus_id)) continue;
if (ext->vtbl->compare_platform_device(ext->device, platform_dev) == 0) if (unix_device_compare(ext->device, platform_dev) == 0)
{ {
ret = ext->device; ret = ext->device;
break; break;
@ -461,7 +547,7 @@ static void mouse_device_create(void)
struct device_create_params params = {{0}}; struct device_create_params params = {{0}};
if (winebus_call(mouse_create, &params)) return; if (winebus_call(mouse_create, &params)) return;
mouse_obj = bus_create_hid_device(&params.desc, &mouse_vtbl, params.device); mouse_obj = bus_create_hid_device(&params.desc, params.device);
IoInvalidateDeviceRelations(bus_pdo, BusRelations); IoInvalidateDeviceRelations(bus_pdo, BusRelations);
} }
@ -470,7 +556,7 @@ static void keyboard_device_create(void)
struct device_create_params params = {{0}}; struct device_create_params params = {{0}};
if (winebus_call(keyboard_create, &params)) return; if (winebus_call(keyboard_create, &params)) return;
keyboard_obj = bus_create_hid_device(&params.desc, &keyboard_vtbl, params.device); keyboard_obj = bus_create_hid_device(&params.desc, params.device);
IoInvalidateDeviceRelations(bus_pdo, BusRelations); IoInvalidateDeviceRelations(bus_pdo, BusRelations);
} }
@ -688,7 +774,7 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
EnterCriticalSection(&ext->cs); EnterCriticalSection(&ext->cs);
if (ext->state != DEVICE_STATE_STOPPED) status = STATUS_SUCCESS; if (ext->state != DEVICE_STATE_STOPPED) status = STATUS_SUCCESS;
else if (ext->state == DEVICE_STATE_REMOVED) status = STATUS_DELETE_PENDING; else if (ext->state == DEVICE_STATE_REMOVED) status = STATUS_DELETE_PENDING;
else if (!(status = ext->vtbl->start_device(device))) ext->state = DEVICE_STATE_STARTED; else if (!(status = unix_device_start(device))) ext->state = DEVICE_STATE_STARTED;
else ERR("failed to start device %p, status %#x\n", device, status); else ERR("failed to start device %p, status %#x\n", device, status);
LeaveCriticalSection(&ext->cs); LeaveCriticalSection(&ext->cs);
break; break;
@ -705,7 +791,7 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
remove_pending_irps(device); remove_pending_irps(device);
bus_unlink_hid_device(device); bus_unlink_hid_device(device);
ext->vtbl->free_device(device); unix_device_remove(device);
ext->cs.DebugInfo->Spare[0] = 0; ext->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&ext->cs); DeleteCriticalSection(&ext->cs);
@ -863,7 +949,7 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
break; break;
} }
irp->IoStatus.Status = ext->vtbl->get_reportdescriptor(device, NULL, 0, &length); irp->IoStatus.Status = unix_device_get_report_descriptor(device, NULL, 0, &length);
if (irp->IoStatus.Status != STATUS_SUCCESS && if (irp->IoStatus.Status != STATUS_SUCCESS &&
irp->IoStatus.Status != STATUS_BUFFER_TOO_SMALL) irp->IoStatus.Status != STATUS_BUFFER_TOO_SMALL)
{ {
@ -886,7 +972,7 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
} }
case IOCTL_HID_GET_REPORT_DESCRIPTOR: case IOCTL_HID_GET_REPORT_DESCRIPTOR:
TRACE("IOCTL_HID_GET_REPORT_DESCRIPTOR\n"); TRACE("IOCTL_HID_GET_REPORT_DESCRIPTOR\n");
irp->IoStatus.Status = ext->vtbl->get_reportdescriptor(device, irp->UserBuffer, buffer_len, &buffer_len); irp->IoStatus.Status = unix_device_get_report_descriptor(device, irp->UserBuffer, buffer_len, &buffer_len);
irp->IoStatus.Information = buffer_len; irp->IoStatus.Information = buffer_len;
break; break;
case IOCTL_HID_GET_STRING: case IOCTL_HID_GET_STRING:
@ -896,7 +982,7 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
irp->IoStatus.Status = hid_get_native_string(device, index, (WCHAR *)irp->UserBuffer, buffer_len / sizeof(WCHAR)); irp->IoStatus.Status = hid_get_native_string(device, index, (WCHAR *)irp->UserBuffer, buffer_len / sizeof(WCHAR));
if (irp->IoStatus.Status != STATUS_SUCCESS) if (irp->IoStatus.Status != STATUS_SUCCESS)
irp->IoStatus.Status = ext->vtbl->get_string(device, index, (WCHAR *)irp->UserBuffer, buffer_len / sizeof(WCHAR)); irp->IoStatus.Status = unix_device_get_string(device, index, (WCHAR *)irp->UserBuffer, buffer_len / sizeof(WCHAR));
if (irp->IoStatus.Status == STATUS_SUCCESS) if (irp->IoStatus.Status == STATUS_SUCCESS)
irp->IoStatus.Information = (strlenW((WCHAR *)irp->UserBuffer) + 1) * sizeof(WCHAR); irp->IoStatus.Information = (strlenW((WCHAR *)irp->UserBuffer) + 1) * sizeof(WCHAR);
break; break;
@ -934,21 +1020,21 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
{ {
HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer); HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
TRACE_(hid_report)("IOCTL_HID_WRITE_REPORT / IOCTL_HID_SET_OUTPUT_REPORT\n"); TRACE_(hid_report)("IOCTL_HID_WRITE_REPORT / IOCTL_HID_SET_OUTPUT_REPORT\n");
ext->vtbl->set_output_report(device, packet, &irp->IoStatus); unix_device_set_output_report(device, packet, &irp->IoStatus);
break; break;
} }
case IOCTL_HID_GET_FEATURE: case IOCTL_HID_GET_FEATURE:
{ {
HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer); HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
TRACE_(hid_report)("IOCTL_HID_GET_FEATURE\n"); TRACE_(hid_report)("IOCTL_HID_GET_FEATURE\n");
ext->vtbl->get_feature_report(device, packet, &irp->IoStatus); unix_device_get_feature_report(device, packet, &irp->IoStatus);
break; break;
} }
case IOCTL_HID_SET_FEATURE: case IOCTL_HID_SET_FEATURE:
{ {
HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer); HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
TRACE_(hid_report)("IOCTL_HID_SET_FEATURE\n"); TRACE_(hid_report)("IOCTL_HID_SET_FEATURE\n");
ext->vtbl->set_feature_report(device, packet, &irp->IoStatus); unix_device_set_feature_report(device, packet, &irp->IoStatus);
break; break;
} }
default: default:

View file

@ -29,8 +29,21 @@
#include "wine/list.h" #include "wine/list.h"
struct unix_device_vtbl
{
void (*destroy)(struct unix_device *iface);
int (*compare)(struct unix_device *iface, void *platform_dev);
NTSTATUS (*start)(struct unix_device *iface, DEVICE_OBJECT *device);
NTSTATUS (*get_report_descriptor)(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *out_length);
NTSTATUS (*get_string)(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length);
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);
};
struct unix_device struct unix_device
{ {
const struct unix_device_vtbl *vtbl;
}; };
extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN; extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN;

View file

@ -30,7 +30,6 @@
#include "wine/list.h" #include "wine/list.h"
#include "wine/unixlib.h" #include "wine/unixlib.h"
#include "bus.h"
#include "unix_private.h" #include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
@ -38,11 +37,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
static struct hid_descriptor mouse_desc; static struct hid_descriptor mouse_desc;
static struct hid_descriptor keyboard_desc; static struct hid_descriptor keyboard_desc;
static void mouse_free_device(DEVICE_OBJECT *device) static void mouse_remove(struct unix_device *iface)
{ {
} }
static NTSTATUS mouse_start_device(DEVICE_OBJECT *device) static int mouse_compare(struct unix_device *iface, void *context)
{
return 0;
}
static NTSTATUS mouse_start(struct unix_device *iface, DEVICE_OBJECT *device)
{ {
if (!hid_descriptor_begin(&mouse_desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE)) if (!hid_descriptor_begin(&mouse_desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE))
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
@ -54,7 +58,7 @@ static NTSTATUS mouse_start_device(DEVICE_OBJECT *device)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS mouse_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length) static NTSTATUS mouse_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
{ {
TRACE("buffer %p, length %u.\n", buffer, length); TRACE("buffer %p, length %u.\n", buffer, length);
@ -65,7 +69,7 @@ static NTSTATUS mouse_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS mouse_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length) static NTSTATUS mouse_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
{ {
static const WCHAR nameW[] = {'W','i','n','e',' ','H','I','D',' ','m','o','u','s','e',0}; static const WCHAR nameW[] = {'W','i','n','e',' ','H','I','D',' ','m','o','u','s','e',0};
if (index != HID_STRING_ID_IPRODUCT) if (index != HID_STRING_ID_IPRODUCT)
@ -76,36 +80,37 @@ static NTSTATUS mouse_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buff
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static void mouse_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void mouse_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
FIXME("id %u, stub!\n", packet->reportId); FIXME("id %u, stub!\n", packet->reportId);
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static void mouse_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) 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); FIXME("id %u, stub!\n", packet->reportId);
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static void mouse_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) 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); FIXME("id %u, stub!\n", packet->reportId);
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
const platform_vtbl mouse_vtbl = static const struct unix_device_vtbl mouse_vtbl =
{ {
.free_device = mouse_free_device, mouse_remove,
.start_device = mouse_start_device, mouse_compare,
.get_reportdescriptor = mouse_get_reportdescriptor, mouse_start,
.get_string = mouse_get_string, mouse_get_report_descriptor,
.set_output_report = mouse_set_output_report, mouse_get_string,
.get_feature_report = mouse_get_feature_report, mouse_set_output_report,
.set_feature_report = mouse_set_feature_report, mouse_get_feature_report,
mouse_set_feature_report,
}; };
static const WCHAR mouse_bus_id[] = {'W','I','N','E','M','O','U','S','E',0}; static const WCHAR mouse_bus_id[] = {'W','I','N','E','M','O','U','S','E',0};
@ -115,7 +120,7 @@ static const struct device_desc mouse_device_desc =
.input = -1, .input = -1,
.serial = {'0','0','0','0',0}, .serial = {'0','0','0','0',0},
}; };
static struct unix_device mouse_device; static struct unix_device mouse_device = {.vtbl = &mouse_vtbl};
static NTSTATUS mouse_device_create(void *args) static NTSTATUS mouse_device_create(void *args)
{ {
@ -125,11 +130,16 @@ static NTSTATUS mouse_device_create(void *args)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static void keyboard_free_device(DEVICE_OBJECT *device) static void keyboard_remove(struct unix_device *iface)
{ {
} }
static NTSTATUS keyboard_start_device(DEVICE_OBJECT *device) static int keyboard_compare(struct unix_device *iface, void *context)
{
return 0;
}
static NTSTATUS keyboard_start(struct unix_device *iface, DEVICE_OBJECT *device)
{ {
if (!hid_descriptor_begin(&keyboard_desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD)) if (!hid_descriptor_begin(&keyboard_desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD))
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
@ -141,7 +151,7 @@ static NTSTATUS keyboard_start_device(DEVICE_OBJECT *device)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS keyboard_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length) static NTSTATUS keyboard_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
{ {
TRACE("buffer %p, length %u.\n", buffer, length); TRACE("buffer %p, length %u.\n", buffer, length);
@ -152,7 +162,7 @@ static NTSTATUS keyboard_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffe
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS keyboard_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length) static NTSTATUS keyboard_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
{ {
static const WCHAR nameW[] = {'W','i','n','e',' ','H','I','D',' ','k','e','y','b','o','a','r','d',0}; static const WCHAR nameW[] = {'W','i','n','e',' ','H','I','D',' ','k','e','y','b','o','a','r','d',0};
if (index != HID_STRING_ID_IPRODUCT) if (index != HID_STRING_ID_IPRODUCT)
@ -163,36 +173,37 @@ static NTSTATUS keyboard_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *b
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static void keyboard_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) static void keyboard_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
{ {
FIXME("id %u, stub!\n", packet->reportId); FIXME("id %u, stub!\n", packet->reportId);
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static void keyboard_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) 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); FIXME("id %u, stub!\n", packet->reportId);
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
static void keyboard_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io) 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); FIXME("id %u, stub!\n", packet->reportId);
io->Information = 0; io->Information = 0;
io->Status = STATUS_NOT_IMPLEMENTED; io->Status = STATUS_NOT_IMPLEMENTED;
} }
const platform_vtbl keyboard_vtbl = static const struct unix_device_vtbl keyboard_vtbl =
{ {
.free_device = keyboard_free_device, keyboard_remove,
.start_device = keyboard_start_device, keyboard_compare,
.get_reportdescriptor = keyboard_get_reportdescriptor, keyboard_start,
.get_string = keyboard_get_string, keyboard_get_report_descriptor,
.set_output_report = keyboard_set_output_report, keyboard_get_string,
.get_feature_report = keyboard_get_feature_report, keyboard_set_output_report,
.set_feature_report = keyboard_set_feature_report, keyboard_get_feature_report,
keyboard_set_feature_report,
}; };
static const WCHAR keyboard_bus_id[] = {'W','I','N','E','K','E','Y','B','O','A','R','D',0}; static const WCHAR keyboard_bus_id[] = {'W','I','N','E','K','E','Y','B','O','A','R','D',0};
@ -202,7 +213,7 @@ static const struct device_desc keyboard_device_desc =
.input = -1, .input = -1,
.serial = {'0','0','0','0',0}, .serial = {'0','0','0','0',0},
}; };
static struct unix_device keyboard_device; static struct unix_device keyboard_device = {.vtbl = &keyboard_vtbl};
static NTSTATUS keyboard_device_create(void *args) static NTSTATUS keyboard_device_create(void *args)
{ {
@ -212,6 +223,65 @@ static NTSTATUS keyboard_device_create(void *args)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS unix_device_remove(void *args)
{
struct unix_device *iface = args;
iface->vtbl->destroy(iface);
return STATUS_SUCCESS;
}
static NTSTATUS unix_device_compare(void *args)
{
struct device_compare_params *params = args;
struct unix_device *iface = params->iface;
return iface->vtbl->compare(iface, params->context);
}
static NTSTATUS unix_device_start(void *args)
{
struct device_start_params *params = args;
struct unix_device *iface = params->iface;
return iface->vtbl->start(iface, params->device);
}
static NTSTATUS unix_device_get_report_descriptor(void *args)
{
struct device_descriptor_params *params = args;
struct unix_device *iface = params->iface;
return iface->vtbl->get_report_descriptor(iface, params->buffer, params->length, params->out_length);
}
static NTSTATUS unix_device_get_string(void *args)
{
struct device_string_params *params = args;
struct unix_device *iface = params->iface;
return iface->vtbl->get_string(iface, params->index, params->buffer, params->length);
}
static NTSTATUS unix_device_set_output_report(void *args)
{
struct device_report_params *params = args;
struct unix_device *iface = params->iface;
iface->vtbl->set_output_report(iface, params->packet, params->io);
return STATUS_SUCCESS;
}
static NTSTATUS unix_device_get_feature_report(void *args)
{
struct device_report_params *params = args;
struct unix_device *iface = params->iface;
iface->vtbl->get_feature_report(iface, params->packet, params->io);
return STATUS_SUCCESS;
}
static NTSTATUS unix_device_set_feature_report(void *args)
{
struct device_report_params *params = args;
struct unix_device *iface = params->iface;
iface->vtbl->set_feature_report(iface, params->packet, params->io);
return STATUS_SUCCESS;
}
const unixlib_entry_t __wine_unix_call_funcs[] = const unixlib_entry_t __wine_unix_call_funcs[] =
{ {
sdl_bus_init, sdl_bus_init,
@ -225,6 +295,14 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
iohid_bus_stop, iohid_bus_stop,
mouse_device_create, mouse_device_create,
keyboard_device_create, keyboard_device_create,
unix_device_remove,
unix_device_compare,
unix_device_start,
unix_device_get_report_descriptor,
unix_device_get_string,
unix_device_set_output_report,
unix_device_get_feature_report,
unix_device_set_feature_report,
}; };
void bus_event_queue_destroy(struct list *queue) void bus_event_queue_destroy(struct list *queue)

View file

@ -25,6 +25,7 @@
#include <winbase.h> #include <winbase.h>
#include <winternl.h> #include <winternl.h>
#include <ddk/wdm.h> #include <ddk/wdm.h>
#include <ddk/hidclass.h>
#include <hidusage.h> #include <hidusage.h>
#include "wine/debug.h" #include "wine/debug.h"
@ -87,6 +88,41 @@ struct device_create_params
struct unix_device *device; struct unix_device *device;
}; };
struct device_compare_params
{
struct unix_device *iface;
void *context;
};
struct device_start_params
{
struct unix_device *iface;
DEVICE_OBJECT *device;
};
struct device_descriptor_params
{
struct unix_device *iface;
BYTE *buffer;
DWORD length;
DWORD *out_length;
};
struct device_string_params
{
struct unix_device *iface;
DWORD index;
WCHAR *buffer;
DWORD length;
};
struct device_report_params
{
struct unix_device *iface;
HID_XFER_PACKET *packet;
IO_STATUS_BLOCK *io;
};
enum unix_funcs enum unix_funcs
{ {
sdl_init, sdl_init,
@ -100,6 +136,14 @@ enum unix_funcs
iohid_stop, iohid_stop,
mouse_create, mouse_create,
keyboard_create, keyboard_create,
device_remove,
device_compare,
device_start,
device_get_report_descriptor,
device_get_string,
device_set_output_report,
device_get_feature_report,
device_set_feature_report,
}; };
extern const unixlib_entry_t __wine_unix_call_funcs[] DECLSPEC_HIDDEN; extern const unixlib_entry_t __wine_unix_call_funcs[] DECLSPEC_HIDDEN;