mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-04 21:07:44 +00:00
hid: Implement HidP_GetLinkCollectionNodes.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Aric Stewart <aric@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9a9af8b39a
commit
56d529694b
|
@ -931,9 +931,27 @@ NTSTATUS WINAPI HidP_GetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, U
|
|||
NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkCollectionNode,
|
||||
ULONG *LinkCollectionNodeLength, PHIDP_PREPARSED_DATA PreparsedData)
|
||||
{
|
||||
FIXME("stub (%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData);
|
||||
WINE_HIDP_PREPARSED_DATA *data = (WINE_HIDP_PREPARSED_DATA*)PreparsedData;
|
||||
WINE_HID_LINK_COLLECTION_NODE *nodes = HID_NODES(data);
|
||||
ULONG i;
|
||||
|
||||
*LinkCollectionNodeLength = 0;
|
||||
TRACE("(%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData);
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
if (*LinkCollectionNodeLength < data->caps.NumberLinkCollectionNodes)
|
||||
return HIDP_STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
for (i = 0; i < data->caps.NumberLinkCollectionNodes; ++i)
|
||||
{
|
||||
LinkCollectionNode[i].LinkUsage = nodes[i].LinkUsage;
|
||||
LinkCollectionNode[i].LinkUsagePage = nodes[i].LinkUsagePage;
|
||||
LinkCollectionNode[i].Parent = nodes[i].Parent;
|
||||
LinkCollectionNode[i].NumberOfChildren = nodes[i].NumberOfChildren;
|
||||
LinkCollectionNode[i].NextSibling = nodes[i].NextSibling;
|
||||
LinkCollectionNode[i].FirstChild = nodes[i].FirstChild;
|
||||
LinkCollectionNode[i].CollectionType = nodes[i].CollectionType;
|
||||
LinkCollectionNode[i].IsAlias = nodes[i].IsAlias;
|
||||
}
|
||||
*LinkCollectionNodeLength = data->caps.NumberLinkCollectionNodes;
|
||||
|
||||
return HIDP_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -51,17 +51,14 @@ static void test_device_info(HANDLE device)
|
|||
trace("Found device %s (%02x, %02x)\n", wine_dbgstr_w(device_name), Caps.UsagePage, Caps.Usage);
|
||||
|
||||
trace("LinkCollectionNodes: (%d)\n", Caps.NumberLinkCollectionNodes);
|
||||
todo_wine
|
||||
ok(Caps.NumberLinkCollectionNodes > 0, "Expected at least one link collection\n");
|
||||
|
||||
nodes_count = 0;
|
||||
status = HidP_GetLinkCollectionNodes(nodes, &nodes_count, ppd);
|
||||
todo_wine
|
||||
ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetLinkCollectionNodes succeeded:%x\n", status);
|
||||
|
||||
nodes_count = ARRAY_SIZE(nodes);
|
||||
status = HidP_GetLinkCollectionNodes(nodes, &nodes_count, ppd);
|
||||
todo_wine
|
||||
ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes failed:%x\n", status);
|
||||
|
||||
for (i = 0; i < nodes_count; ++i)
|
||||
|
@ -74,13 +71,9 @@ static void test_device_info(HANDLE device)
|
|||
nodes[i].CollectionType, nodes[i].IsAlias, nodes[i].UserContext);
|
||||
}
|
||||
|
||||
todo_wine
|
||||
ok(nodes_count > 0, "Unexpected number of link collection nodes:%u.\n", nodes_count);
|
||||
todo_wine
|
||||
ok(nodes[0].LinkUsagePage == Caps.UsagePage, "Unexpected top collection usage page:%x\n", nodes[0].LinkUsagePage);
|
||||
todo_wine
|
||||
ok(nodes[0].LinkUsage == Caps.Usage, "Unexpected top collection usage:%x\n", nodes[0].LinkUsage);
|
||||
todo_wine
|
||||
ok(nodes[0].CollectionType == 1, "Unexpected top collection type:%x\n", nodes[0].CollectionType);
|
||||
|
||||
rc = HidD_FreePreparsedData(ppd);
|
||||
|
|
|
@ -835,12 +835,14 @@ static void create_preparse_ctx(const struct collection *base, struct preparse_c
|
|||
create_preparse_ctx(c, ctx);
|
||||
}
|
||||
|
||||
static void preparse_collection(const struct collection *base,
|
||||
static void preparse_collection(const struct collection *root, const struct collection *base,
|
||||
WINE_HIDP_PREPARSED_DATA *data, struct preparse_ctx *ctx)
|
||||
{
|
||||
WINE_HID_ELEMENT *elem = HID_ELEMS(data);
|
||||
WINE_HID_LINK_COLLECTION_NODE *nodes = HID_NODES(data);
|
||||
struct feature *f;
|
||||
struct collection *c;
|
||||
struct list *entry;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(f, &base->features, struct feature, entry)
|
||||
{
|
||||
|
@ -885,11 +887,29 @@ static void preparse_collection(const struct collection *base,
|
|||
}
|
||||
}
|
||||
|
||||
if (root != base)
|
||||
{
|
||||
nodes[base->index].LinkUsagePage = base->caps.UsagePage;
|
||||
nodes[base->index].LinkUsage = base->caps.u.NotRange.Usage;
|
||||
nodes[base->index].Parent = base->parent == root ? 0 : base->parent->index;
|
||||
nodes[base->index].CollectionType = base->type;
|
||||
nodes[base->index].IsAlias = 0;
|
||||
|
||||
if ((entry = list_head(&base->collections)))
|
||||
nodes[base->index].FirstChild = LIST_ENTRY(entry, struct collection, entry)->index;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(c, &base->collections, struct collection, entry)
|
||||
preparse_collection(c, data, ctx);
|
||||
{
|
||||
preparse_collection(root, c, data, ctx);
|
||||
|
||||
if ((entry = list_next(&base->collections, &c->entry)))
|
||||
nodes[c->index].NextSibling = LIST_ENTRY(entry, struct collection, entry)->index;
|
||||
if (root != base) nodes[base->index].NumberOfChildren++;
|
||||
}
|
||||
}
|
||||
|
||||
static WINE_HIDP_PREPARSED_DATA* build_PreparseData(struct collection *base_collection)
|
||||
static WINE_HIDP_PREPARSED_DATA* build_PreparseData(struct collection *base_collection, unsigned int node_count)
|
||||
{
|
||||
WINE_HIDP_PREPARSED_DATA *data;
|
||||
unsigned int report_count;
|
||||
|
@ -897,6 +917,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(struct collection *base_coll
|
|||
|
||||
struct preparse_ctx ctx;
|
||||
unsigned int element_off;
|
||||
unsigned int nodes_offset;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
create_preparse_ctx(base_collection, &ctx);
|
||||
|
@ -906,14 +927,19 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(struct collection *base_coll
|
|||
element_off = FIELD_OFFSET(WINE_HIDP_PREPARSED_DATA, reports[report_count]);
|
||||
size = element_off + (ctx.elem_count * sizeof(WINE_HID_ELEMENT));
|
||||
|
||||
nodes_offset = size;
|
||||
size += node_count * sizeof(WINE_HID_LINK_COLLECTION_NODE);
|
||||
|
||||
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
|
||||
data->magic = HID_MAGIC;
|
||||
data->dwSize = size;
|
||||
data->caps.Usage = base_collection->caps.u.NotRange.Usage;
|
||||
data->caps.UsagePage = base_collection->caps.UsagePage;
|
||||
data->caps.NumberLinkCollectionNodes = node_count;
|
||||
data->elementOffset = element_off;
|
||||
data->nodesOffset = nodes_offset;
|
||||
|
||||
preparse_collection(base_collection, data, &ctx);
|
||||
preparse_collection(base_collection, base_collection, data, &ctx);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -981,7 +1007,7 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
|
|||
}
|
||||
}
|
||||
|
||||
data = build_PreparseData(base);
|
||||
data = build_PreparseData(base, cidx);
|
||||
debug_print_preparsed(data);
|
||||
free_collection(base);
|
||||
|
||||
|
|
|
@ -48,6 +48,17 @@ typedef struct __WINE_HID_REPORT
|
|||
DWORD elementIdx;
|
||||
} WINE_HID_REPORT;
|
||||
|
||||
typedef struct __WINE_HID_LINK_COLLECTION_NODE {
|
||||
USAGE LinkUsage;
|
||||
USAGE LinkUsagePage;
|
||||
USHORT Parent;
|
||||
USHORT NumberOfChildren;
|
||||
USHORT NextSibling;
|
||||
USHORT FirstChild;
|
||||
BYTE CollectionType;
|
||||
BYTE IsAlias;
|
||||
} WINE_HID_LINK_COLLECTION_NODE;
|
||||
|
||||
typedef struct __WINE_HIDP_PREPARSED_DATA
|
||||
{
|
||||
DWORD magic;
|
||||
|
@ -55,6 +66,7 @@ typedef struct __WINE_HIDP_PREPARSED_DATA
|
|||
HIDP_CAPS caps;
|
||||
|
||||
DWORD elementOffset;
|
||||
DWORD nodesOffset;
|
||||
DWORD reportCount[3];
|
||||
BYTE reportIdx[3][256];
|
||||
|
||||
|
@ -65,5 +77,6 @@ typedef struct __WINE_HIDP_PREPARSED_DATA
|
|||
#define HID_OUTPUT_REPORTS(d) ((d)->reports + (d)->reportCount[0])
|
||||
#define HID_FEATURE_REPORTS(d) ((d)->reports + (d)->reportCount[0] + (d)->reportCount[1])
|
||||
#define HID_ELEMS(d) ((WINE_HID_ELEMENT*)((BYTE*)(d) + (d)->elementOffset))
|
||||
#define HID_NODES(d) ((WINE_HID_LINK_COLLECTION_NODE*)((BYTE*)(d) + (d)->nodesOffset))
|
||||
|
||||
#endif /* __WINE_PARSE_H */
|
||||
|
|
Loading…
Reference in a new issue