Commit 6ae7e808 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winebus.sys: Use HID descriptor helpers in bus_sdl.c.

And remove old helpers. Signed-off-by: 's avatarRémi Bernon <rbernon@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 40e44557
...@@ -16,6 +16,14 @@ ...@@ -16,6 +16,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winternl.h>
#include <ddk/wdm.h>
#include <hidusage.h>
typedef int(*enum_func)(DEVICE_OBJECT *device, void *context); typedef int(*enum_func)(DEVICE_OBJECT *device, void *context);
/* Buses */ /* Buses */
...@@ -57,3 +65,24 @@ BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN; ...@@ -57,3 +65,24 @@ 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;
struct hid_descriptor
{
BYTE *data;
SIZE_T size;
SIZE_T max_size;
};
extern BOOL hid_descriptor_append(struct hid_descriptor *desc, const BYTE *buffer, SIZE_T size) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_begin(struct hid_descriptor *desc, USAGE usage_page, USAGE usage) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_end(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
extern void hid_descriptor_free(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_buttons(struct hid_descriptor *desc, USAGE usage_page,
USAGE usage_min, USAGE usage_max) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_padding(struct hid_descriptor *desc, BYTE bitcount) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_hatswitch(struct hid_descriptor *desc, INT count) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_axes(struct hid_descriptor *desc, BYTE count, USAGE usage_page,
const USAGE *usages, BOOL rel, INT size, LONG min, LONG max) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_haptics(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
...@@ -78,7 +78,6 @@ ...@@ -78,7 +78,6 @@
#define LE_DWORD(x) (x) #define LE_DWORD(x) (x)
#endif #endif
#include "controller.h"
#include "bus.h" #include "bus.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
......
/*
* Common controller functions and structures
*
* Copyright 2018 Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <hidusage.h>
struct hid_descriptor
{
BYTE *data;
SIZE_T size;
SIZE_T max_size;
};
extern BOOL hid_descriptor_append(struct hid_descriptor *desc, const BYTE *buffer, SIZE_T size) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_begin(struct hid_descriptor *desc, USAGE usage_page, USAGE usage) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_end(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
extern void hid_descriptor_free(struct hid_descriptor *desc) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_buttons(struct hid_descriptor *desc, USAGE usage_page,
USAGE usage_min, USAGE usage_max) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_padding(struct hid_descriptor *desc, BYTE bitcount) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_hatswitch(struct hid_descriptor *desc, INT count) DECLSPEC_HIDDEN;
extern BOOL hid_descriptor_add_axes(struct hid_descriptor *desc, BYTE count, USAGE usage_page,
const USAGE *usages, BOOL rel, INT size, LONG min, LONG max) DECLSPEC_HIDDEN;
/* Blocks of data for building HID device descriptions */
#include "psh_hid_macros.h"
static const BYTE REPORT_HEADER[] = {
USAGE_PAGE(1, /* placeholder */ HID_USAGE_PAGE_GENERIC),
USAGE(1, 0),
COLLECTION(1, Application),
USAGE(1, /* placeholder */ HID_USAGE_GENERIC_POINTER),
COLLECTION(1, Physical),
};
#define IDX_HEADER_PAGE 1
#define IDX_HEADER_USAGE 3
static const BYTE REPORT_BUTTONS[] = {
USAGE_PAGE(1, /* placeholder */ HID_USAGE_PAGE_BUTTON),
USAGE_MINIMUM(1, /* placeholder */ 1),
USAGE_MAXIMUM(1, /* placeholder */ 3),
LOGICAL_MINIMUM(1, 0),
LOGICAL_MAXIMUM(1, 1),
PHYSICAL_MINIMUM(1, 0),
PHYSICAL_MAXIMUM(1, 1),
REPORT_COUNT(1, /* placeholder */ 3),
REPORT_SIZE(1, 1),
INPUT(1, Data|Var|Abs),
};
#define IDX_BUTTON_USAGE_PAGE 1
#define IDX_BUTTON_MIN_USAGE 3
#define IDX_BUTTON_MAX_USAGE 5
#define IDX_BUTTON_COUNT 15
static const BYTE REPORT_PADDING[] = {
REPORT_COUNT(1, /* placeholder */ 3),
REPORT_SIZE(1, 1),
INPUT(1, Cnst|Var|Abs),
};
#define IDX_PADDING_BIT_COUNT 1
static const BYTE REPORT_AXIS_HEADER[] = {
USAGE_PAGE(1, /* placeholder */ HID_USAGE_PAGE_GENERIC),
};
#define IDX_AXIS_PAGE 1
static const BYTE REPORT_AXIS_USAGE[] = {
USAGE(1, /* placeholder */ HID_USAGE_GENERIC_X),
};
#define IDX_AXIS_USAGE 1
static const BYTE REPORT_REL_AXIS_TAIL[] = {
LOGICAL_MINIMUM(1, 0x81),
LOGICAL_MAXIMUM(1, 0x7f),
REPORT_SIZE(1, 8),
REPORT_COUNT(1, /* placeholder */ 2),
INPUT(1, Data|Var|Rel),
};
#define IDX_REL_AXIS_COUNT 7
static const BYTE REPORT_HATSWITCH[] = {
USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
USAGE(1, HID_USAGE_GENERIC_HATSWITCH),
LOGICAL_MINIMUM(1, 1),
LOGICAL_MAXIMUM(1, 8),
PHYSICAL_MINIMUM(1, 0),
PHYSICAL_MAXIMUM(1, 8),
REPORT_SIZE(1, 4),
REPORT_COUNT(1, /* placeholder */ 1),
INPUT(1, Data|Var|Abs),
};
#define IDX_HATSWITCH_COUNT 15
static const BYTE REPORT_TAIL[] = {
END_COLLECTION,
END_COLLECTION,
};
#include "pop_hid_macros.h"
static inline BYTE *add_button_block(BYTE* report_ptr, BYTE usage_min, BYTE usage_max)
{
memcpy(report_ptr, REPORT_BUTTONS, sizeof(REPORT_BUTTONS));
report_ptr[IDX_BUTTON_MIN_USAGE] = usage_min;
report_ptr[IDX_BUTTON_MAX_USAGE] = usage_max;
report_ptr[IDX_BUTTON_COUNT] = (usage_max - usage_min) + 1;
return report_ptr + sizeof(REPORT_BUTTONS);
}
static inline BYTE *add_padding_block(BYTE *report_ptr, BYTE bitcount)
{
memcpy(report_ptr, REPORT_PADDING, sizeof(REPORT_PADDING));
report_ptr[IDX_PADDING_BIT_COUNT] = bitcount;
return report_ptr + sizeof(REPORT_PADDING);
}
static inline BYTE *add_hatswitch(BYTE *report_ptr, INT count)
{
memcpy(report_ptr, REPORT_HATSWITCH, sizeof(REPORT_HATSWITCH));
report_ptr[IDX_HATSWITCH_COUNT] = count;
return report_ptr + sizeof(REPORT_HATSWITCH);
}
...@@ -18,7 +18,16 @@ ...@@ -18,7 +18,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "controller.h" #include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"
#include "winioctl.h"
#include "hidusage.h"
#include "ddk/wdm.h"
#include "bus.h"
BOOL hid_descriptor_append(struct hid_descriptor *desc, const BYTE *buffer, SIZE_T size) BOOL hid_descriptor_append(struct hid_descriptor *desc, const BYTE *buffer, SIZE_T size)
{ {
...@@ -209,4 +218,31 @@ BOOL hid_descriptor_add_axes(struct hid_descriptor *desc, BYTE count, USAGE usag ...@@ -209,4 +218,31 @@ BOOL hid_descriptor_add_axes(struct hid_descriptor *desc, BYTE count, USAGE usag
return TRUE; return TRUE;
} }
BOOL hid_descriptor_add_haptics(struct hid_descriptor *desc)
{
static const BYTE template[] =
{
USAGE_PAGE(2, HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN),
USAGE(1, 0x01),
/* padding */
REPORT_COUNT(1, 0x02),
REPORT_SIZE(1, 0x08),
OUTPUT(1, Data|Var|Abs),
/* actuators */
LOGICAL_MINIMUM(1, 0x00),
LOGICAL_MAXIMUM(1, 0xff),
PHYSICAL_MINIMUM(1, 0x00),
PHYSICAL_MAXIMUM(1, 0xff),
REPORT_SIZE(1, 0x08),
REPORT_COUNT(1, 0x02),
OUTPUT(1, Data|Var|Abs),
/* padding */
REPORT_COUNT(1, 0x02),
REPORT_SIZE(1, 0x08),
OUTPUT(1, Data|Var|Abs),
};
return hid_descriptor_append(desc, template, sizeof(template));
}
#include "pop_hid_macros.h" #include "pop_hid_macros.h"
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "wine/list.h" #include "wine/list.h"
#include "bus.h" #include "bus.h"
#include "controller.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
WINE_DECLARE_DEBUG_CHANNEL(hid_report); WINE_DECLARE_DEBUG_CHANNEL(hid_report);
......
...@@ -460,7 +460,6 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre ...@@ -460,7 +460,6 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre
todo_wine_if(xi_caps.Flags & XINPUT_CAPS_FFB_SUPPORTED) todo_wine_if(xi_caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)
check_member(*hid_caps, expect_hid_caps, "%d", OutputReportByteLength); check_member(*hid_caps, expect_hid_caps, "%d", OutputReportByteLength);
check_member(*hid_caps, expect_hid_caps, "%d", FeatureReportByteLength); check_member(*hid_caps, expect_hid_caps, "%d", FeatureReportByteLength);
todo_wine
check_member(*hid_caps, expect_hid_caps, "%d", NumberLinkCollectionNodes); check_member(*hid_caps, expect_hid_caps, "%d", NumberLinkCollectionNodes);
check_member(*hid_caps, expect_hid_caps, "%d", NumberInputButtonCaps); check_member(*hid_caps, expect_hid_caps, "%d", NumberInputButtonCaps);
todo_wine todo_wine
...@@ -479,20 +478,16 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre ...@@ -479,20 +478,16 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre
length = hid_caps->NumberLinkCollectionNodes; length = hid_caps->NumberLinkCollectionNodes;
status = HidP_GetLinkCollectionNodes(collections, &length, preparsed); status = HidP_GetLinkCollectionNodes(collections, &length, preparsed);
ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes returned %#x\n", status); ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes returned %#x\n", status);
todo_wine
ok(length == ARRAY_SIZE(expect_collections), "got %d collections\n", length); ok(length == ARRAY_SIZE(expect_collections), "got %d collections\n", length);
for (i = 0; i < min(length, ARRAY_SIZE(expect_collections)); ++i) for (i = 0; i < min(length, ARRAY_SIZE(expect_collections)); ++i)
{ {
winetest_push_context("collections[%d]", i); winetest_push_context("collections[%d]", i);
todo_wine_if(i == 1)
check_member(collections[i], expect_collections[i], "%04x", LinkUsage); check_member(collections[i], expect_collections[i], "%04x", LinkUsage);
check_member(collections[i], expect_collections[i], "%04x", LinkUsagePage); check_member(collections[i], expect_collections[i], "%04x", LinkUsagePage);
check_member(collections[i], expect_collections[i], "%d", Parent); check_member(collections[i], expect_collections[i], "%d", Parent);
todo_wine_if(i == 0)
check_member(collections[i], expect_collections[i], "%d", NumberOfChildren); check_member(collections[i], expect_collections[i], "%d", NumberOfChildren);
check_member(collections[i], expect_collections[i], "%d", NextSibling); check_member(collections[i], expect_collections[i], "%d", NextSibling);
todo_wine_if(i == 0)
check_member(collections[i], expect_collections[i], "%d", FirstChild); check_member(collections[i], expect_collections[i], "%d", FirstChild);
check_member(collections[i], expect_collections[i], "%d", CollectionType); check_member(collections[i], expect_collections[i], "%d", CollectionType);
check_member(collections[i], expect_collections[i], "%d", IsAlias); check_member(collections[i], expect_collections[i], "%d", IsAlias);
...@@ -511,9 +506,7 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre ...@@ -511,9 +506,7 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre
check_member(button_caps[i], expect_button_caps[i], "%d", ReportID); check_member(button_caps[i], expect_button_caps[i], "%d", ReportID);
check_member(button_caps[i], expect_button_caps[i], "%d", IsAlias); check_member(button_caps[i], expect_button_caps[i], "%d", IsAlias);
check_member(button_caps[i], expect_button_caps[i], "%d", BitField); check_member(button_caps[i], expect_button_caps[i], "%d", BitField);
todo_wine
check_member(button_caps[i], expect_button_caps[i], "%d", LinkCollection); check_member(button_caps[i], expect_button_caps[i], "%d", LinkCollection);
todo_wine
check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsage); check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsage);
check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsagePage); check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsagePage);
check_member(button_caps[i], expect_button_caps[i], "%d", IsRange); check_member(button_caps[i], expect_button_caps[i], "%d", IsRange);
...@@ -569,9 +562,9 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre ...@@ -569,9 +562,9 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre
check_member(value_caps[i], expect_value_caps[i], "%d", IsAlias); check_member(value_caps[i], expect_value_caps[i], "%d", IsAlias);
todo_wine_if(i == 5) todo_wine_if(i == 5)
check_member(value_caps[i], expect_value_caps[i], "%d", BitField); check_member(value_caps[i], expect_value_caps[i], "%d", BitField);
todo_wine_if(i >= 2) todo_wine_if(i == 5)
check_member(value_caps[i], expect_value_caps[i], "%d", LinkCollection); check_member(value_caps[i], expect_value_caps[i], "%d", LinkCollection);
todo_wine todo_wine_if(i == 5)
check_member(value_caps[i], expect_value_caps[i], "%d", LinkUsage); check_member(value_caps[i], expect_value_caps[i], "%d", LinkUsage);
check_member(value_caps[i], expect_value_caps[i], "%d", LinkUsagePage); check_member(value_caps[i], expect_value_caps[i], "%d", LinkUsagePage);
check_member(value_caps[i], expect_value_caps[i], "%d", IsRange); check_member(value_caps[i], expect_value_caps[i], "%d", IsRange);
...@@ -597,7 +590,7 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre ...@@ -597,7 +590,7 @@ static void check_hid_caps(DWORD index, HANDLE device, PHIDP_PREPARSED_DATA pre
if (!value_caps[i].IsRange && !expect_value_caps[i].IsRange) if (!value_caps[i].IsRange && !expect_value_caps[i].IsRange)
{ {
todo_wine todo_wine_if(i >= 4)
check_member(value_caps[i], expect_value_caps[i], "%04x", NotRange.Usage); check_member(value_caps[i], expect_value_caps[i], "%04x", NotRange.Usage);
todo_wine_if(i == 5) todo_wine_if(i == 5)
check_member(value_caps[i], expect_value_caps[i], "%d", NotRange.DataIndex); check_member(value_caps[i], expect_value_caps[i], "%d", NotRange.DataIndex);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment