winebus.sys: Compute offsets while building the report descriptor.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
fa3905bafa
commit
de050c974b
|
@ -32,8 +32,12 @@
|
||||||
#include "hidusage.h"
|
#include "hidusage.h"
|
||||||
#include "ddk/wdm.h"
|
#include "ddk/wdm.h"
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
|
||||||
#include "unix_private.h"
|
#include "unix_private.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
|
||||||
|
|
||||||
static BOOL hid_report_descriptor_append(struct hid_report_descriptor *desc, const BYTE *buffer, SIZE_T size)
|
static BOOL hid_report_descriptor_append(struct hid_report_descriptor *desc, const BYTE *buffer, SIZE_T size)
|
||||||
{
|
{
|
||||||
BYTE *tmp = desc->data;
|
BYTE *tmp = desc->data;
|
||||||
|
@ -93,6 +97,25 @@ BOOL hid_device_end_report_descriptor(struct unix_device *iface)
|
||||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL hid_device_add_button_count(struct unix_device *iface, BYTE count)
|
||||||
|
{
|
||||||
|
USHORT offset = iface->hid_device_state.bit_size / 8;
|
||||||
|
|
||||||
|
if ((iface->hid_device_state.bit_size % 8) && !iface->hid_device_state.button_count)
|
||||||
|
ERR("buttons should start byte aligned, missing padding!\n");
|
||||||
|
else if (iface->hid_device_state.bit_size + count > 0x80000)
|
||||||
|
ERR("report size overflow, too many elements!\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!iface->hid_device_state.button_count) iface->hid_device_state.button_start = offset;
|
||||||
|
iface->hid_device_state.button_count += count;
|
||||||
|
iface->hid_device_state.bit_size += count;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page, USAGE usage_min, USAGE usage_max)
|
BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page, USAGE usage_min, USAGE usage_max)
|
||||||
{
|
{
|
||||||
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
||||||
|
@ -117,6 +140,9 @@ BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page, USAGE u
|
||||||
INPUT(1, Cnst|Var|Abs),
|
INPUT(1, Cnst|Var|Abs),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!hid_device_add_button_count(iface, usage_max - usage_min + 1))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!hid_report_descriptor_append(desc, template, sizeof(template)))
|
if (!hid_report_descriptor_append(desc, template, sizeof(template)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -126,6 +152,27 @@ BOOL hid_device_add_buttons(struct unix_device *iface, USAGE usage_page, USAGE u
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL hid_device_add_hatswitch_count(struct unix_device *iface, BYTE count)
|
||||||
|
{
|
||||||
|
USHORT offset = iface->hid_device_state.bit_size / 8;
|
||||||
|
|
||||||
|
if (iface->hid_device_state.button_count)
|
||||||
|
ERR("hatswitches should be added before buttons!\n");
|
||||||
|
else if ((iface->hid_device_state.bit_size % 8))
|
||||||
|
ERR("hatswitches should be byte aligned, missing padding!\n");
|
||||||
|
else if (iface->hid_device_state.bit_size + 8 * count > 0x80000)
|
||||||
|
ERR("report size overflow, too many elements!\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!iface->hid_device_state.hatswitch_count) iface->hid_device_state.hatswitch_start = offset;
|
||||||
|
iface->hid_device_state.hatswitch_count += count;
|
||||||
|
iface->hid_device_state.bit_size += 8 * count;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
|
BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
|
||||||
{
|
{
|
||||||
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
|
||||||
|
@ -143,9 +190,42 @@ BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
|
||||||
INPUT(1, Data|Var|Abs|Null),
|
INPUT(1, Data|Var|Abs|Null),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!hid_device_add_hatswitch_count(iface, count))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return hid_report_descriptor_append(desc, template, sizeof(template));
|
return hid_report_descriptor_append(desc, template, sizeof(template));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL hid_device_add_axis_count(struct unix_device *iface, BOOL rel, BYTE count)
|
||||||
|
{
|
||||||
|
USHORT offset = iface->hid_device_state.bit_size / 8;
|
||||||
|
|
||||||
|
if (!rel && iface->hid_device_state.rel_axis_count)
|
||||||
|
ERR("absolute axes should be added before relative axes!\n");
|
||||||
|
else if (iface->hid_device_state.button_count || iface->hid_device_state.hatswitch_count)
|
||||||
|
ERR("axes should be added before buttons or hatswitches!\n");
|
||||||
|
else if ((iface->hid_device_state.bit_size % 8))
|
||||||
|
ERR("axes should be byte aligned, missing padding!\n");
|
||||||
|
else if (iface->hid_device_state.bit_size + 32 * count > 0x80000)
|
||||||
|
ERR("report size overflow, too many elements!\n");
|
||||||
|
else if (rel)
|
||||||
|
{
|
||||||
|
if (!iface->hid_device_state.rel_axis_count) iface->hid_device_state.rel_axis_start = offset;
|
||||||
|
iface->hid_device_state.rel_axis_count += count;
|
||||||
|
iface->hid_device_state.bit_size += 32 * count;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!iface->hid_device_state.abs_axis_count) iface->hid_device_state.abs_axis_start = offset;
|
||||||
|
iface->hid_device_state.abs_axis_count += count;
|
||||||
|
iface->hid_device_state.bit_size += 32 * count;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page,
|
BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page,
|
||||||
const USAGE *usages, BOOL rel, LONG min, LONG max)
|
const USAGE *usages, BOOL rel, LONG min, LONG max)
|
||||||
{
|
{
|
||||||
|
@ -171,6 +251,9 @@ BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usage_page
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!hid_device_add_axis_count(iface, rel, count))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!hid_report_descriptor_append(desc, template_begin, sizeof(template_begin)))
|
if (!hid_report_descriptor_append(desc, template_begin, sizeof(template_begin)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,19 @@ struct hid_report_descriptor
|
||||||
SIZE_T max_size;
|
SIZE_T max_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hid_device_state
|
||||||
|
{
|
||||||
|
ULONG bit_size;
|
||||||
|
USHORT abs_axis_start;
|
||||||
|
USHORT abs_axis_count;
|
||||||
|
USHORT rel_axis_start;
|
||||||
|
USHORT rel_axis_count;
|
||||||
|
USHORT hatswitch_start;
|
||||||
|
USHORT hatswitch_count;
|
||||||
|
USHORT button_start;
|
||||||
|
USHORT button_count;
|
||||||
|
};
|
||||||
|
|
||||||
struct unix_device
|
struct unix_device
|
||||||
{
|
{
|
||||||
const struct raw_device_vtbl *vtbl;
|
const struct raw_device_vtbl *vtbl;
|
||||||
|
@ -65,6 +78,7 @@ struct unix_device
|
||||||
|
|
||||||
const struct hid_device_vtbl *hid_vtbl;
|
const struct hid_device_vtbl *hid_vtbl;
|
||||||
struct hid_report_descriptor hid_report_descriptor;
|
struct hid_report_descriptor hid_report_descriptor;
|
||||||
|
struct hid_device_state hid_device_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
|
extern void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue