summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/hidapi
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
committer3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
commit5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch)
tree8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/hidapi
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/hidapi')
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/AUTHORS.txt18
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/BUILD.autotools.md114
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/BUILD.cmake.md280
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/BUILD.md127
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/CMakeLists.txt108
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/HACKING.txt19
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/LICENSE-bsd.txt26
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/LICENSE-gpl3.txt674
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/LICENSE-orig.txt9
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/LICENSE.txt13
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/Makefile.am85
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/README.md196
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi.c1750
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_android.h26
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_c.h35
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_ios.h26
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_libusb.h134
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_linux.h47
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_mac.h25
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_netbsd.h25
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_steamxbox.h23
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_windows.h82
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/VERSION1
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/android/hid.cpp1477
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/android/hid.h39
-rwxr-xr-xcontrib/SDL-3.2.8/src/hidapi/bootstrap2
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/configure.ac256
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/dist/hidapi.podspec31
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-drop-down.pngbin0 -> 22316 bytes
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-highlights.pngbin0 -> 77327 bytes
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/doxygen/Doxyfile2724
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/doxygen/main_page.md13
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/hidapi/hidapi.h634
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/hidtest/CMakeLists.txt40
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/hidtest/Makefile.am28
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/hidtest/test.c316
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/ios/hid.m1038
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/CMakeLists.txt107
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/Makefile-manual22
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.am34
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.freebsd39
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.haiku39
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.linux42
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/hid.c2144
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_libusb.h56
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h174
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h202
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/linux/CMakeLists.txt38
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/linux/Makefile-manual42
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/linux/Makefile.am10
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/linux/hid.c1492
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/m4/ax_pthread.m4309
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/m4/pkg.m4157
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/mac/CMakeLists.txt48
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/mac/Makefile-manual27
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/mac/Makefile.am9
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/mac/hid.c1594
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/mac/hidapi_darwin.h98
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/meson.build22
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/netbsd/CMakeLists.txt35
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/netbsd/README.md29
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/netbsd/hid.c1173
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/pc/hidapi-hidraw.pc.in11
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/pc/hidapi-libusb.pc.in11
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/pc/hidapi-netbsd.pc.in11
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/pc/hidapi.pc.in11
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/src/CMakeLists.txt206
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/src/cmake/hidapi-config.cmake.in61
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/subprojects/README.md2
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/subprojects/hidapi_build_cmake/CMakeLists.txt10
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/Makefile-manual26
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.am43
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.freebsd33
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.linux32
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mac46
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mingw32
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist28
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo1
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.stringsbin0 -> 92 bytes
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icnsbin0 -> 21918 bytes
-rwxr-xr-xcontrib/SDL-3.2.8/src/hidapi/testgui/copy_to_bundle.sh98
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/mac_support.h17
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/mac_support_cocoa.m103
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/test.cpp532
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/testgui.sln20
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/testgui/testgui.vcproj217
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/udev/69-hid.rules36
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/CMakeLists.txt63
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/Makefile-manual14
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/Makefile.am15
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/Makefile.mingw30
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hid.c1728
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi.rc35
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi.sln41
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcproj200
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcxproj200
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi_cfgmgr32.h86
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.c990
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.h254
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidclass.h40
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidpi.h72
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidsdi.h59
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidapi_winapi.h74
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcproj196
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcxproj176
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/CMakeLists.txt15
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/README.md122
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/pp_data_dump.c238
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/CMakeLists.txt76
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001.pp_data420
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_expected.rpt_desc12
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_real.rpt_desc64
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001.pp_data183
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_expected.rpt_desc7
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_real.rpt_desc7
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C.pp_data532
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_expected.rpt_desc16
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_real.rpt_desc61
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C.pp_data97
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_expected.rpt_desc3
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_real.rpt_desc38
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00.pp_data139
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_expected.rpt_desc4
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_real.rpt_desc39
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001.pp_data302
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_expected.rpt_desc8
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_real.rpt_desc61
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00.pp_data139
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_expected.rpt_desc4
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_real.rpt_desc39
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001.pp_data185
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_expected.rpt_desc7
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_real.rpt_desc58
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001.pp_data252
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_expected.rpt_desc5
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_real.rpt_desc24
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001.pp_data520
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_expected.rpt_desc18
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_real.rpt_desc18
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C.pp_data93
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_expected.rpt_desc3
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_real.rpt_desc12
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00.pp_data139
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_expected.rpt_desc4
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_real.rpt_desc13
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001.pp_data302
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_expected.rpt_desc8
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_real.rpt_desc33
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00.pp_data139
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_expected.rpt_desc4
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_real.rpt_desc13
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C.pp_data93
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_expected.rpt_desc3
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_real.rpt_desc18
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00.pp_data139
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_expected.rpt_desc4
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_real.rpt_desc20
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001.pp_data302
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_expected.rpt_desc8
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_real.rpt_desc44
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00.pp_data139
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_expected.rpt_desc4
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_real.rpt_desc22
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001.pp_data185
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_expected.rpt_desc7
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_real.rpt_desc42
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001.pp_data185
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_expected.rpt_desc4
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_real.rpt_desc22
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C.pp_data385
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_expected.rpt_desc10
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_real.rpt_desc47
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0.pp_data1255
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_expected.rpt_desc24
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_real.rpt_desc113
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B.pp_data461
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_expected.rpt_desc17
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_real.rpt_desc68
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01.pp_data11508
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_expected.rpt_desc75
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_real.rpt_desc381
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/windows/test/hid_report_reconstructor_test.c563
182 files changed, 44867 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/hidapi/AUTHORS.txt b/contrib/SDL-3.2.8/src/hidapi/AUTHORS.txt
new file mode 100644
index 0000000..7c2a035
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/AUTHORS.txt
@@ -0,0 +1,18 @@
1
2HIDAPI Authors:
3
4Alan Ott <alan@signal11.us>:
5 Original Author and Maintainer
6 Linux, Windows, and Mac implementations
7
8Ludovic Rousseau <rousseau@debian.org>:
9 Formatting for Doxygen documentation
10 Bug fixes
11 Correctness fixes
12
13libusb/hidapi Team:
14 Development/maintenance since June 4th 2019
15
16For a comprehensive list of contributions, see the commit list at github:
17 https://github.com/libusb/hidapi/graphs/contributors
18
diff --git a/contrib/SDL-3.2.8/src/hidapi/BUILD.autotools.md b/contrib/SDL-3.2.8/src/hidapi/BUILD.autotools.md
new file mode 100644
index 0000000..24b20a5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/BUILD.autotools.md
@@ -0,0 +1,114 @@
1# Building HIDAPI using Autotools (deprecated)
2
3---
4**NOTE**: for all intentions and purposes the Autotools build scripts for HIDAPI are _deprecated_ and going to be obsolete in the future.
5HIDAPI Team recommends using CMake build for HIDAPI.
6If you are already using Autotools build scripts provided by HIDAPI,
7consider switching to CMake build scripts as soon as possible.
8
9---
10
11To be able to use Autotools to build HIDAPI, it has to be [installed](#installing-autotools)/available in the system.
12
13Make sure you've checked [prerequisites](BUILD.md#prerequisites) and installed all required dependencies.
14
15## Installing Autotools
16
17HIDAPI uses few specific tools/packages from Autotools: `autoconf`, `automake`, `libtool`.
18
19On different platforms or package managers, those could be named a bit differently or packaged together.
20You'll have to check the documentation/package list for your specific package manager.
21
22### Linux
23
24On Ubuntu the tools are available via APT:
25
26```sh
27sudo apt install autoconf automake libtool
28```
29
30### FreeBSD
31
32FreeBSD Autotools can be installed as:
33
34```sh
35pkg_add -r autotools
36```
37
38Additionally, on FreeBSD you will need to install GNU make:
39```sh
40pkg_add -r gmake
41```
42
43## Building HIDAPI with Autotools
44
45A simple command list, to build HIDAPI with Autotools as a _shared library_ and install in into your system:
46
47```sh
48./bootstrap # this prepares the configure script
49./configure
50make # build the library
51make install # as root, or using sudo, this will install hidapi into your system
52```
53
54`./configure` can take several arguments which control the build. A few commonly used options:
55```sh
56 --enable-testgui
57 # Enable the build of Foxit-based Test GUI. This requires Fox toolkit to
58 # be installed/available. See README.md#test-gui for remarks.
59
60 --prefix=/usr
61 # Specify where you want the output headers and libraries to
62 # be installed. The example above will put the headers in
63 # /usr/include and the binaries in /usr/lib. The default is to
64 # install into /usr/local which is fine on most systems.
65
66 --disable-shared
67 # By default, both shared and static libraries are going to be built/installed.
68 # This option disables shared library build, if only static library is required.
69```
70
71
72## Cross Compiling
73
74This section talks about cross compiling HIDAPI for Linux using Autotools.
75This is useful for using HIDAPI on embedded Linux targets. These
76instructions assume the most raw kind of embedded Linux build, where all
77prerequisites will need to be built first. This process will of course vary
78based on your embedded Linux build system if you are using one, such as
79OpenEmbedded or Buildroot.
80
81For the purpose of this section, it will be assumed that the following
82environment variables are exported.
83```sh
84$ export STAGING=$HOME/out
85$ export HOST=arm-linux
86```
87
88`STAGING` and `HOST` can be modified to suit your setup.
89
90### Prerequisites
91
92Depending on what backend you want to cross-compile, you also need to prepare the dependencies:
93`libusb` for libusb HIDAPI backend, or `libudev` for hidraw HIDAPI backend.
94
95An example of cross-compiling `libusb`. From `libusb` source directory, run:
96```sh
97./configure --host=$HOST --prefix=$STAGING
98make
99make install
100```
101
102An example of cross-comping `libudev` is not covered by this section.
103Check `libudev`'s documentation for details.
104
105### Building HIDAPI
106
107Build HIDAPI:
108```sh
109PKG_CONFIG_DIR= \
110PKG_CONFIG_LIBDIR=$STAGING/lib/pkgconfig:$STAGING/share/pkgconfig \
111PKG_CONFIG_SYSROOT_DIR=$STAGING \
112./configure --host=$HOST --prefix=$STAGING
113# make / make install - same as for a regular build
114```
diff --git a/contrib/SDL-3.2.8/src/hidapi/BUILD.cmake.md b/contrib/SDL-3.2.8/src/hidapi/BUILD.cmake.md
new file mode 100644
index 0000000..573f910
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/BUILD.cmake.md
@@ -0,0 +1,280 @@
1# Building HIDAPI using CMake
2
3To build HIDAPI with CMake, it has to be [installed](#installing-cmake)/available in the system.
4
5Make sure you've checked [prerequisites](BUILD.md#prerequisites) and installed all required dependencies.
6
7HIDAPI CMake build system allows you to build HIDAPI in two generally different ways:
81) As a [standalone package/library](#standalone-package-build);
92) As [part of a larger CMake project](#hidapi-as-a-subdirectory).
10
11**TL;DR**: if you're experienced developer and have been working with CMake projects or have been written some of your own -
12most of this document may not be of interest for you; just check variables names, its default values and the target names.
13
14## Installing CMake
15
16CMake can be installed either using your system's package manager,
17or by downloading an installer/prebuilt version from the [official website](https://cmake.org/download/).
18
19On most \*nix systems, the preferred way to install CMake is via package manager,
20e.g. `sudo apt install cmake`.
21
22On Windows CMake could be provided by your development environment (e.g. by Visual Studio Installer or MinGW installer),
23or you may install it system-wise using the installer from the official website.
24
25On macOS CMake may be installed by Homebrew/MacPorts or using the installer from the official website.
26
27## Standalone package build
28
29To build HIDAPI as a standalone package, you follow [general steps](https://cmake.org/runningcmake/) of building any CMake project.
30
31An example of building HIDAPI with CMake:
32```sh
33# precondition: create a <build dir> somewhere on the filesystem (preferably outside of the HIDAPI source)
34# this is the place where all intermediate/build files are going to be located
35cd <build dir>
36# configure the build
37cmake <HIDAPI source dir>
38# build it!
39cmake --build .
40# install library; by default installs into /usr/local/
41cmake --build . --target install
42# NOTE: you need to run install command as root, to be able to install into /usr/local/
43```
44Such invocation will use the default (as per CMake magic) compiler/build environment available in your system.
45
46You may pass some additional CMake variables to control the build configuration as `-D<CMake Variable>=value`.
47E.g.:
48```sh
49# install command now would install things into /usr
50cmake <HIDAPI source dir> -DCMAKE_INSTALL_PREFIX=/usr
51```
52
53<details>
54 <summary>Using a specific CMake generator</summary>
55
56An example of using `Ninja` as a CMake generator:
57
58```sh
59cd <build dir>
60# configure the build
61cmake -GNinja <HIDAPI source dir>
62# we know, that CMake has generated build files for Ninja,
63# so we can use `ninja` directly, instead of `cmake --build .`
64ninja
65# install library
66ninja install
67```
68
69`-G` here specifies a native build system CMake would generate build files for.
70Check [CMake Documentation](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) for a list of available generators (system-specific).
71
72</details><br>
73
74Some of the [standard](https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html) CMake variables you may want to use to configure a build:
75
76- [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html) - prefix where `install` target would install the library(ies);
77- [`CMAKE_BUILD_TYPE`](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) - standard possible values: `Debug`, `Release`, `RelWithDebInfo`, `MinSizeRel`; Defaults to `Release` for HIDAPI, if not specified;
78- [`BUILD_SHARED_LIBS`](https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html) - when set to TRUE, HIDAPI is built as a shared library, otherwise build statically; Defaults to `TRUE` for HIDAPI, if not specified;
79
80<details>
81 <summary>macOS-specific variables</summary>
82
83 - [`CMAKE_FRAMEWORK`](https://cmake.org/cmake/help/latest/variable/CMAKE_FRAMEWORK.html) - (since CMake 3.15) when set to TRUE, HIDAPI is built as a framework library, otherwise build as a regular static/shared library; Defaults to `FALSE` for HIDAPI, if not specified;
84 - [`CMAKE_OSX_DEPLOYMENT_TARGET`](https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_DEPLOYMENT_TARGET.html) - minimum version of the target platform (e.g. macOS or iOS) on which the target binaries are to be deployed; defaults to a maximum supported target platform by currently used XCode/Toolchain;
85
86</details><br>
87
88HIDAPI-specific CMake variables:
89
90- `HIDAPI_BUILD_HIDTEST` - when set to TRUE, build a small test application `hidtest`;
91- `HIDAPI_WITH_TESTS` - when set to TRUE, build all (unit-)tests;
92currently this option is only available on Windows, since only Windows backend has tests;
93
94<details>
95 <summary>Linux-specific variables</summary>
96
97 - `HIDAPI_WITH_HIDRAW` - when set to TRUE, build HIDRAW-based implementation of HIDAPI (`hidapi-hidraw`), otherwise don't build it; defaults to TRUE;
98 - `HIDAPI_WITH_LIBUSB` - when set to TRUE, build LIBUSB-based implementation of HIDAPI (`hidapi-libusb`), otherwise don't build it; defaults to TRUE;
99
100 **NOTE**: at least one of `HIDAPI_WITH_HIDRAW` or `HIDAPI_WITH_LIBUSB` has to be set to TRUE.
101
102</details><br>
103
104To see all most-useful CMake variables available for HIDAPI, one of the most convenient ways is too use [`cmake-gui`](https://cmake.org/cmake/help/latest/manual/cmake-gui.1.html) tool ([example](https://cmake.org/runningcmake/)).
105
106_NOTE_: HIDAPI packages built by CMake can be used with `pkg-config`, as if built with [Autotools](BUILD.autotools.md).
107
108### MSVC and Ninja
109It is possible to build a CMake project (including HIDAPI) using MSVC compiler and Ninja (for medium and larger projects it is so much faster than msbuild).
110
111For that:
1121) Open cmd.exe;
1132) Setup MSVC build environment variables, e.g.: `vcvarsall.bat x64`, where:
114 - `vcvarsall.bat` is an environment setup script of your MSVC toolchain installation;<br>For MSVC 2019 Community edition it is located at: `C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\`;
115 - `x64` -a target architecture to build;
1163) Follow general build steps, and use `Ninja` as a generator.
117
118### Using HIDAPI in a CMake project
119
120When HIDAPI is used as a standalone package (either installed into the system or built manually and installed elsewhere), the simplest way to use it is as showed in the example:
121
122```cmake
123project(my_application)
124
125add_executable(my_application main.c)
126
127find_package(hidapi REQUIRED)
128target_link_libraries(my_application PRIVATE hidapi::hidapi)
129```
130
131If HIDAPI isn't installed in your system, or `find_package` cannot find HIDAPI by default for any other reasons,
132the recommended way manually specify which HIDAPI package to use is via `hidapi_ROOT` CMake variable, e.g.:
133`-Dhidapi_ROOT=<path to HIDAPI installation prefix>`.
134
135_NOTE_: usage of `hidapi_ROOT` is only possible (and recommended) with CMake 3.12 and higher. For older versions of CMake you'd need to specify [`CMAKE_PREFIX_PATH`](https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html#variable:CMAKE_PREFIX_PATH) instead.
136
137Check with [`find_package`](https://cmake.org/cmake/help/latest/command/find_package.html) documentation if you need more details.
138
139Available CMake targets after successful `find_package(hidapi)`:
140- `hidapi::hidapi` - indented to be used in most cases;
141- `hidapi::include` - if you need only to include `<hidapi.h>` but not link against the library;
142- `hidapi::winapi` - same as `hidapi::hidapi` on Windows; available only on Windows;
143- `hidapi::darwin` - same as `hidapi::hidapi` on macOS; available only on macOS;
144- `hidapi::libusb` - available when libusb backend is used/available;
145- `hidapi::hidraw` - available when hidraw backend is used/available on Linux;
146
147**NOTE**: on Linux often both `hidapi::libusb` and `hidapi::hidraw` backends are available; in that case `hidapi::hidapi` is an alias for **`hidapi::hidraw`**. The motivation is that `hidraw` backend is a native Linux kernel implementation of HID protocol, and supports various HID devices (USB, Bluetooth, I2C, etc.). If `hidraw` backend isn't built at all (`hidapi::libusb` is the only target) - `hidapi::hidapi` is an alias for `hidapi::libusb`.
148If you're developing a cross-platform application and you are sure you need to use `libusb` backend on Linux, the simple way to achieve this is:
149```cmake
150if(TARGET hidapi::libusb)
151 target_link_libraries(my_project PRIVATE hidapi::libusb)
152else()
153 target_link_libraries(my_project PRIVATE hidapi::hidapi)
154endif()
155```
156
157## HIDAPI as a subdirectory
158
159HIDAPI can be easily used as a subdirectory of a larger CMake project:
160```cmake
161# root CMakeLists.txt
162cmake_minimum_required(VERSION 3.4.3...3.25 FATAL_ERROR)
163
164add_subdirectory(hidapi)
165add_subdirectory(my_application)
166
167# my_application/CMakeLists.txt
168project(my_application)
169
170add_executable(my_application main.c)
171
172# NOTE: no `find_package` is required, since HIDAPI targets are already a part of the project tree
173target_link_libraries(my_application PRIVATE hidapi::hidapi)
174```
175Lets call this "larger project" a "host project".
176
177All of the variables described in [standalone build](#standalone-package-build) section can be used to control HIDAPI build in case of a subdirectory, e.g.:
178```cmake
179set(HIDAPI_WITH_LIBUSB FALSE) # surely will be used only on Linux
180set(BUILD_SHARED_LIBS FALSE) # HIDAPI as static library on all platforms
181add_subdirectory(hidapi)
182```
183
184<details>
185 <summary>NOTE</summary>
186
187 If you project happen to use `BUILD_SHARED_LIBS` as a `CACHE` variable globally for you project, setting it as simple variable, as showed above _will have not affect_ up until _CMake 3.13_. See [CMP0077](https://cmake.org/cmake/help/latest/policy/CMP0077.html) for details.
188</details><br>
189
190There are several important differences in the behavior of HIDAPI CMake build system when CMake is built as standalone package vs subdirectory build:
191
1921) In _standalone build_ a number of standard and HIDAPI-specific variables are marked as _cache variables_ or _options_.
193This is done for convenience: when you're building HIDAPI as a standalone package and using tools like `cmake-gui` - those are highlighted as variables that can be changed and has some short description/documentation. E.g.:
194![an example of highlighted variables in cmake-gui](documentation/cmake-gui-highlights.png "cmake-gui highlighted variables")<br>
195E.g.2:<br>
196![an example of drop-down menu in cmake-gui](documentation/cmake-gui-drop-down.png "cmake-gui drop-down menu")<br>
197When HIDAPI is built as a _subdirectory_ - **_none of the variables are marked for cache or as options_** by HIDAPI.
198This is done to let the host project's developer decide what is important (what needs to be highlighted) and what's not.
199
2002) The default behavior/default value for some of the variables is a bit different:
201 - by default, none of HIDAPI targets are [installed](https://cmake.org/cmake/help/latest/command/install.html); if required, HIDAPI targets can be installed by host project _after_ including HIDAPI subdirectory (requires CMake 3.13 or later); **or**, the default installation can be enabled by setting `HIDAPI_INSTALL_TARGETS` variable _before_ including HIDAPI subdirectory.
202 HIDAPI uses [GNUInstallDirs](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) to specify install locations. Variables like `CMAKE_INSTALL_LIBDIR` can be used to control HIDAPI's installation locations. E.g.:
203 ```cmake
204 # enable the installation if you need it
205 set(HIDAPI_INSTALL_TARGETS ON)
206 # (optionally) change default installation locations if it makes sense for your target platform, etc.
207 set(CMAKE_INSTALL_LIBDIR "lib64")
208 add_subdirectory(hidapi)
209 ```
210 - HIDAPI prints its version during the configuration when built as a standalone package; to enable this for subdirectory builds - set `HIDAPI_PRINT_VERSION` to TRUE before including HIDAPI;
211
2123) In a subdirectory build, HIDAPI _doesn't modify or set any of the CMake variables_ that may change the build behavior.
213 For instance, in a _standalone build_, if CMAKE_BUILD_TYPE or BUILD_SHARED_LIBS variables are not set, those are defaulted to "Release" and "TRUE" explicitly.
214 In a _subdirectory build_, even if not set, those variables remain unchanged, so a host project's developer has a full control over the HIDAPI build configuration.
215
216Available CMake targets after `add_subdirectory(hidapi)` _are the same as in case of [standalone build](#standalone-package-build)_, and a few additional ones:
217- `hidapi_include` - the interface library; `hidapi::include` is an alias of it;
218- `hidapi_winapi` - library target on Windows; `hidapi::winapi` is an alias of it;
219- `hidapi_darwin` - library target on macOS; `hidapi::darwin` is an alias of it;
220- `hidapi_libusb` - library target for libusb backend; `hidapi::libusb` is an alias of it;
221- `hidapi_hidraw` - library target for hidraw backend; `hidapi::hidraw` is an alias of it;
222- `hidapi-libusb` - an alias of `hidapi_libusb` for compatibility with raw library name;
223- `hidapi-hidraw` - an alias of `hidapi_hidraw` for compatibility with raw library name;
224- `hidapi` - an alias of `hidapi_winapi` or `hidapi_darwin` on Windows or macOS respectfully.
225
226Advanced:
227- Why would I need additional targets described in this section above, if I already have alias targets compatible with `find_package`?
228 - an example:
229 ```cmake
230 add_subdirectory(hidapi)
231 if(TARGET hidapi_libusb)
232 # see libusb/hid.c for usage of `NO_ICONV`
233 target_compile_definitions(hidapi_libusb PRIVATE NO_ICONV)
234 endif()
235 ```
236
237## Both Shared and Static build
238
239If you're a former (or present) user of Autotools build scripts for HIDAPI, or you're a package manager maintainer and you're often working with those - you're likely asking how to build HIDAPI with CMake and get both Shared and Static libraries (as would be done by Autotools: `./configure --enable-static --enable-shared ...`).
240
241CMake doesn't have such option of-the-box and it is decided not to introduce any manual CMake-level workarounds for HIDAPI on this matter.
242
243If you want to mimic the Autotools behavior, it is possible by building/installing first the static version of the library and then shared version of the library. The installation folder (`CMAKE_INSTALL_PREFIX`) should point to the same directory for both variants, that way:
244- both static and shared library binaries will be available and usable;
245- a single header file(s) for both of them;
246- Autotools/pkg-config (`.pc`) files will be generated and usable _as if_ generated by Autotools natively and build configured with both `-enable-static --enable-shared` options;
247- CMake package scripts will be generated and fully usable, but _only the last build installed_, i.e. if the last was installed Shared version of the binary - CMake targets found by `find_package(hidapi)` would point to a Shared binaries.
248
249There is a historical discussion, why such solution is simplest/preferable: https://github.com/libusb/hidapi/issues/424
250
251#### TL;DR/Sample
252
253```sh
254# First - configure/build
255
256# Static libraries
257cmake -S <HIDAPI source dir> -B "<build dir>/static" -DCMAKE_INSTALL_PREFIX=<your installation prefix> -DBUILD_SHARED_LIBS=FALSE
258cmake --build "<build dir>/static"
259# Shared libraries
260cmake -S <HIDAPI source dir> -B "<build dir>/shared" -DCMAKE_INSTALL_PREFIX=<your installation prefix> -DBUILD_SHARED_LIBS=TRUE
261cmake --build "<build dir>/shared"
262
263# (Optionally) change the installation destination.
264# NOTE1: this is supported by CMake only on UNIX platforms
265# See https://cmake.org/cmake/help/latest/envvar/DESTDIR.html
266# NOTE2: this is not the same as `CMAKE_INSTALL_PREFIX` set above
267# NOTE3: this is only required if you have a staging dir other than the final runtime dir,
268# e.g. during cross-compilation
269export DESTDIR="$STAGING_DIR"
270
271#
272# Install the libraries
273# NOTE: order of installation matters - install Shared variant *the last*
274
275# Static libraries
276cmake --install "<build dir>/static"
277# Shared libraries
278cmake --install "<build dir>/shared"
279
280```
diff --git a/contrib/SDL-3.2.8/src/hidapi/BUILD.md b/contrib/SDL-3.2.8/src/hidapi/BUILD.md
new file mode 100644
index 0000000..d7a3546
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/BUILD.md
@@ -0,0 +1,127 @@
1# Building HIDAPI from Source
2
3## Table of content
4
5* [Intro](#intro)
6* [Prerequisites](#prerequisites)
7 * [Linux](#linux)
8 * [FreeBSD](#freebsd)
9 * [Mac](#mac)
10 * [Windows](#windows)
11* [Embedding HIDAPI directly into your source tree](#embedding-hidapi-directly-into-your-source-tree)
12* [Building the manual way on Unix platforms](#building-the-manual-way-on-unix-platforms)
13* [Building on Windows](#building-on-windows)
14
15## Intro
16
17For various reasons, you may need to build HIDAPI on your own.
18
19It can be done in several different ways:
20- using [CMake](BUILD.cmake.md);
21- using [Autotools](BUILD.autotools.md) (deprecated);
22- using [manual makefiles](#building-the-manual-way-on-unix-platforms);
23- using `Meson` (requires CMake);
24
25**Autotools** build system is historically the first mature build system for
26HIDAPI. The most common usage of it is in its separate README: [BUILD.autotools.md](BUILD.autotools.md).<br/>
27NOTE: for all intentions and purposes the Autotools build scripts for HIDAPI are _deprecated_ and going to be obsolete in the future.
28HIDAPI Team recommends using CMake build for HIDAPI.
29
30**CMake** build system is de facto an industry standard for many open-source and proprietary projects and solutions.
31HIDAPI is one of the projects which use the power of CMake to its advantage.
32More documentation is available in its separate README: [BUILD.cmake.md](BUILD.cmake.md).
33
34**Meson** build system for HIDAPI is designed as a [wrapper](https://mesonbuild.com/CMake-module.html) over CMake build script.
35It is present for the convenience of Meson users who need to use HIDAPI and need to be sure HIDAPI is built in accordance with officially supported build scripts.<br>
36In the Meson script of your project you need a `hidapi = subproject('hidapi')` subproject, and `hidapi.get_variable('hidapi_dep')` as your dependency.
37There are also backend/platform-specific dependencies available: `hidapi_winapi`, `hidapi_darwin`, `hidapi_hidraw`, `hidapi_libusb`.
38
39If you don't know where to start to build HIDAPI, we recommend starting with [CMake](BUILD.cmake.md) build.
40
41## Prerequisites:
42
43Regardless of what build system you choose to use, there are specific dependencies for each platform/backend.
44
45### Linux:
46
47Depending on which backend you're going to build, you'll need to install
48additional development packages. For `linux/hidraw` backend, you need a
49development package for `libudev`. For `libusb` backend, naturally, you need
50`libusb` development package.
51
52On Debian/Ubuntu systems these can be installed by running:
53```sh
54# required only by hidraw backend
55sudo apt install libudev-dev
56# required only by libusb backend
57sudo apt install libusb-1.0-0-dev
58```
59
60### FreeBSD:
61
62On FreeBSD, you will need to install libiconv. This is done by running
63the following:
64```sh
65pkg_add -r libiconv
66```
67
68### Mac:
69
70Make sure you have XCode installed and its Command Line Tools.
71
72### Windows:
73
74You just need a compiler. You may use Visual Studio or Cygwin/MinGW,
75depending on which environment is best for your needs.
76
77## Embedding HIDAPI directly into your source tree
78
79Instead of using one of the provided standalone build systems,
80you may want to integrate HIDAPI directly into your source tree.
81
82---
83If your project uses CMake as a build system, it is safe to add HIDAPI as a [subdirectory](BUILD.cmake.md#hidapi-as-a-subdirectory).
84
85---
86If _the only option_ that works for you is adding HIDAPI sources directly
87to your project's build system, then you need:
88- include a _single source file_ into your project's build system,
89depending on your platform and the backend you want to use:
90 - [`windows\hid.c`](windows/hid.c);
91 - [`linux/hid.c`](linux/hid.c);
92 - [`libusb/hid.c`](libusb/hid.c);
93 - [`mac/hid.c`](mac/hid.c);
94- add a [`hidapi`](hidapi) folder to the include path when building `hid.c`;
95- make the platform/backend specific [dependencies](#prerequisites) available during the compilation/linking, when building `hid.c`;
96
97NOTE: the above doesn't guarantee that having a copy of `<backend>/hid.c` and `hidapi/hidapi.h` is enough to build HIDAPI.
98The only guarantee that `<backend>/hid.c` includes all necessary sources to compile it as a single file.
99
100Check the manual makefiles for a simple example/reference of what are the dependencies of each specific backend.
101
102## Building the manual way on Unix platforms
103
104Manual Makefiles are provided mostly to give the user an idea what it takes
105to build a program which embeds HIDAPI directly inside of it. These should
106really be used as examples only. If you want to build a system-wide shared
107library, use one of the build systems mentioned above.
108
109To build HIDAPI using the manual Makefiles, change the directory
110of your platform and run make. For example, on Linux run:
111```sh
112cd linux/
113make -f Makefile-manual
114```
115
116## Building on Windows
117
118To build the HIDAPI DLL on Windows using Visual Studio, build the `.sln` file
119in the `windows/` directory.
120
121To build HIDAPI using MinGW or Cygwin using Autotools, use general Autotools
122 [instruction](BUILD.autotools.md).
123
124Any windows builds (MSVC or MinGW/Cygwin) are also supported by [CMake](BUILD.cmake.md).
125
126If you are looking for information regarding DDK build of HIDAPI:
127- the build has been broken for a while and now the support files are obsolete.
diff --git a/contrib/SDL-3.2.8/src/hidapi/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/CMakeLists.txt
new file mode 100644
index 0000000..d708681
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/CMakeLists.txt
@@ -0,0 +1,108 @@
1cmake_minimum_required(VERSION 3.1.3...3.25 FATAL_ERROR)
2
3if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
4 add_subdirectory(src)
5 # compatibility with find_package() vs add_subdirectory
6 set(hidapi_VERSION "${hidapi_VERSION}" PARENT_SCOPE)
7 return()
8endif()
9# All of the below in this file is meant for a standalone build.
10# When building as a subdirectory of a larger project, most of the options may not make sense for it,
11# so it is up to developer to configure those, e.g.:
12#
13# # a subfolder of a master project, e.g.: 3rdparty/hidapi/CMakeLists.txt
14#
15# set(HIDAPI_WITH_HIDRAW OFF)
16# set(CMAKE_FRAMEWORK ON)
17# # and keep everything else to their defaults
18# add_subdirectory(hidapi)
19#
20
21set(DEFAULT_CMAKE_BUILD_TYPES "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
22if(NOT DEFINED CMAKE_BUILD_TYPE OR NOT CMAKE_BUILD_TYPE)
23 set(CMAKE_BUILD_TYPE "Release" CACHE STRING "${DEFAULT_CMAKE_BUILD_TYPES}" FORCE)
24endif()
25# This part is for convenience, when used one of the standard build types with cmake-gui
26list(FIND DEFAULT_CMAKE_BUILD_TYPES "${CMAKE_BUILD_TYPE}" _build_type_index)
27if(${_build_type_index} GREATER -1)
28 # set it optionally, so a custom CMAKE_BUILD_TYPE can be used as well, if needed
29 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${DEFAULT_CMAKE_BUILD_TYPES})
30endif()
31unset(_build_type_index)
32#
33
34project(hidapi LANGUAGES C)
35
36if(APPLE)
37 if(NOT CMAKE_VERSION VERSION_LESS "3.15")
38 option(CMAKE_FRAMEWORK "Build macOS/iOS Framework version of the library" OFF)
39 endif()
40elseif(NOT WIN32)
41 if(CMAKE_SYSTEM_NAME MATCHES "Linux")
42 option(HIDAPI_WITH_HIDRAW "Build HIDRAW-based implementation of HIDAPI" ON)
43 option(HIDAPI_WITH_LIBUSB "Build LIBUSB-based implementation of HIDAPI" ON)
44 endif()
45 if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
46 option(HIDAPI_WITH_NETBSD "Build NetBSD/UHID implementation of HIDAPI" ON)
47 endif()
48endif()
49
50option(BUILD_SHARED_LIBS "Build shared version of the libraries, otherwise build statically" ON)
51
52set(HIDAPI_INSTALL_TARGETS ON)
53set(HIDAPI_PRINT_VERSION ON)
54
55set(IS_DEBUG_BUILD OFF)
56if(CMAKE_BUILD_TYPE STREQUAL "Debug")
57 set(IS_DEBUG_BUILD ON)
58endif()
59
60option(HIDAPI_ENABLE_ASAN "Build HIDAPI with ASAN address sanitizer instrumentation" OFF)
61
62if(HIDAPI_ENABLE_ASAN)
63 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
64 if(MSVC)
65 # the default is to have "/INCREMENTAL" which causes a warning when "-fsanitize=address" is present
66 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO")
67 set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO")
68 set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
69 set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
70 endif()
71endif()
72
73if(WIN32)
74 # so far only Windows has tests
75 option(HIDAPI_WITH_TESTS "Build HIDAPI (unit-)tests" ${IS_DEBUG_BUILD})
76else()
77 set(HIDAPI_WITH_TESTS OFF)
78endif()
79
80if(HIDAPI_WITH_TESTS)
81 enable_testing()
82endif()
83
84if(WIN32)
85 option(HIDAPI_BUILD_PP_DATA_DUMP "Build small Windows console application pp_data_dump.exe" ${IS_DEBUG_BUILD})
86endif()
87
88add_subdirectory(src)
89
90option(HIDAPI_BUILD_HIDTEST "Build small console test application hidtest" ${IS_DEBUG_BUILD})
91if(HIDAPI_BUILD_HIDTEST)
92 add_subdirectory(hidtest)
93endif()
94
95if(HIDAPI_ENABLE_ASAN)
96 if(NOT MSVC)
97 # MSVC doesn't recognize those options, other compilers - requiring it
98 foreach(HIDAPI_TARGET hidapi_winapi hidapi_darwin hidapi_hidraw hidapi_libusb hidtest_hidraw hidtest_libusb hidtest)
99 if(TARGET ${HIDAPI_TARGET})
100 if(BUILD_SHARED_LIBS)
101 target_link_options(${HIDAPI_TARGET} PRIVATE -fsanitize=address)
102 else()
103 target_link_options(${HIDAPI_TARGET} PUBLIC -fsanitize=address)
104 endif()
105 endif()
106 endforeach()
107 endif()
108endif()
diff --git a/contrib/SDL-3.2.8/src/hidapi/HACKING.txt b/contrib/SDL-3.2.8/src/hidapi/HACKING.txt
new file mode 100644
index 0000000..e06b533
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/HACKING.txt
@@ -0,0 +1,19 @@
1This file is mostly for the maintainer.
2
3Updating a Version:
41. Update VERSION file.
52. HID_API_VERSION_MAJOR/HID_API_VERSION_MINOR/HID_API_VERSION_PATCH in hidapi.h.
6
7Before firing a new release:
81. Run the "Checks" Githtub Action
92. Make sure no defects are found at: https://scan.coverity.com/projects/hidapi
103. Fix if any
11
12Firing a new release:
131. Update the Version (if not yet updated).
142. Prepare the Release Notes.
153. Store the Release Notes into a file.
164. Create locally an annotated git tag with release notes attached, e.g.: `git tag -aF ../hidapi_release_notes hidapi-<VERSION>`
175. Push newly created tag: `git push origin hidapi-<VERSION>`
186. Grab the hidapi-win.zip from Summary page of "GitHub Builds" Action for latest master build.
197. Create a Github Release with hidapi-win.zip attached, for newly created tag.
diff --git a/contrib/SDL-3.2.8/src/hidapi/LICENSE-bsd.txt b/contrib/SDL-3.2.8/src/hidapi/LICENSE-bsd.txt
new file mode 100644
index 0000000..538cdf9
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/LICENSE-bsd.txt
@@ -0,0 +1,26 @@
1Copyright (c) 2010, Alan Ott, Signal 11 Software
2All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice,
8 this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of Signal 11 Software nor the names of its
13 contributors may be used to endorse or promote products derived from
14 this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26POSSIBILITY OF SUCH DAMAGE.
diff --git a/contrib/SDL-3.2.8/src/hidapi/LICENSE-gpl3.txt b/contrib/SDL-3.2.8/src/hidapi/LICENSE-gpl3.txt
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/LICENSE-gpl3.txt
@@ -0,0 +1,674 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 3, 29 June 2007
3
4 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The GNU General Public License is a free, copyleft license for
11software and other kinds of works.
12
13 The licenses for most software and other practical works are designed
14to take away your freedom to share and change the works. By contrast,
15the GNU General Public License is intended to guarantee your freedom to
16share and change all versions of a program--to make sure it remains free
17software for all its users. We, the Free Software Foundation, use the
18GNU General Public License for most of our software; it applies also to
19any other work released this way by its authors. You can apply it to
20your programs, too.
21
22 When we speak of free software, we are referring to freedom, not
23price. Our General Public Licenses are designed to make sure that you
24have the freedom to distribute copies of free software (and charge for
25them if you wish), that you receive source code or can get it if you
26want it, that you can change the software or use pieces of it in new
27free programs, and that you know you can do these things.
28
29 To protect your rights, we need to prevent others from denying you
30these rights or asking you to surrender the rights. Therefore, you have
31certain responsibilities if you distribute copies of the software, or if
32you modify it: responsibilities to respect the freedom of others.
33
34 For example, if you distribute copies of such a program, whether
35gratis or for a fee, you must pass on to the recipients the same
36freedoms that you received. You must make sure that they, too, receive
37or can get the source code. And you must show them these terms so they
38know their rights.
39
40 Developers that use the GNU GPL protect your rights with two steps:
41(1) assert copyright on the software, and (2) offer you this License
42giving you legal permission to copy, distribute and/or modify it.
43
44 For the developers' and authors' protection, the GPL clearly explains
45that there is no warranty for this free software. For both users' and
46authors' sake, the GPL requires that modified versions be marked as
47changed, so that their problems will not be attributed erroneously to
48authors of previous versions.
49
50 Some devices are designed to deny users access to install or run
51modified versions of the software inside them, although the manufacturer
52can do so. This is fundamentally incompatible with the aim of
53protecting users' freedom to change the software. The systematic
54pattern of such abuse occurs in the area of products for individuals to
55use, which is precisely where it is most unacceptable. Therefore, we
56have designed this version of the GPL to prohibit the practice for those
57products. If such problems arise substantially in other domains, we
58stand ready to extend this provision to those domains in future versions
59of the GPL, as needed to protect the freedom of users.
60
61 Finally, every program is threatened constantly by software patents.
62States should not allow patents to restrict development and use of
63software on general-purpose computers, but in those that do, we wish to
64avoid the special danger that patents applied to a free program could
65make it effectively proprietary. To prevent this, the GPL assures that
66patents cannot be used to render the program non-free.
67
68 The precise terms and conditions for copying, distribution and
69modification follow.
70
71 TERMS AND CONDITIONS
72
73 0. Definitions.
74
75 "This License" refers to version 3 of the GNU General Public License.
76
77 "Copyright" also means copyright-like laws that apply to other kinds of
78works, such as semiconductor masks.
79
80 "The Program" refers to any copyrightable work licensed under this
81License. Each licensee is addressed as "you". "Licensees" and
82"recipients" may be individuals or organizations.
83
84 To "modify" a work means to copy from or adapt all or part of the work
85in a fashion requiring copyright permission, other than the making of an
86exact copy. The resulting work is called a "modified version" of the
87earlier work or a work "based on" the earlier work.
88
89 A "covered work" means either the unmodified Program or a work based
90on the Program.
91
92 To "propagate" a work means to do anything with it that, without
93permission, would make you directly or secondarily liable for
94infringement under applicable copyright law, except executing it on a
95computer or modifying a private copy. Propagation includes copying,
96distribution (with or without modification), making available to the
97public, and in some countries other activities as well.
98
99 To "convey" a work means any kind of propagation that enables other
100parties to make or receive copies. Mere interaction with a user through
101a computer network, with no transfer of a copy, is not conveying.
102
103 An interactive user interface displays "Appropriate Legal Notices"
104to the extent that it includes a convenient and prominently visible
105feature that (1) displays an appropriate copyright notice, and (2)
106tells the user that there is no warranty for the work (except to the
107extent that warranties are provided), that licensees may convey the
108work under this License, and how to view a copy of this License. If
109the interface presents a list of user commands or options, such as a
110menu, a prominent item in the list meets this criterion.
111
112 1. Source Code.
113
114 The "source code" for a work means the preferred form of the work
115for making modifications to it. "Object code" means any non-source
116form of a work.
117
118 A "Standard Interface" means an interface that either is an official
119standard defined by a recognized standards body, or, in the case of
120interfaces specified for a particular programming language, one that
121is widely used among developers working in that language.
122
123 The "System Libraries" of an executable work include anything, other
124than the work as a whole, that (a) is included in the normal form of
125packaging a Major Component, but which is not part of that Major
126Component, and (b) serves only to enable use of the work with that
127Major Component, or to implement a Standard Interface for which an
128implementation is available to the public in source code form. A
129"Major Component", in this context, means a major essential component
130(kernel, window system, and so on) of the specific operating system
131(if any) on which the executable work runs, or a compiler used to
132produce the work, or an object code interpreter used to run it.
133
134 The "Corresponding Source" for a work in object code form means all
135the source code needed to generate, install, and (for an executable
136work) run the object code and to modify the work, including scripts to
137control those activities. However, it does not include the work's
138System Libraries, or general-purpose tools or generally available free
139programs which are used unmodified in performing those activities but
140which are not part of the work. For example, Corresponding Source
141includes interface definition files associated with source files for
142the work, and the source code for shared libraries and dynamically
143linked subprograms that the work is specifically designed to require,
144such as by intimate data communication or control flow between those
145subprograms and other parts of the work.
146
147 The Corresponding Source need not include anything that users
148can regenerate automatically from other parts of the Corresponding
149Source.
150
151 The Corresponding Source for a work in source code form is that
152same work.
153
154 2. Basic Permissions.
155
156 All rights granted under this License are granted for the term of
157copyright on the Program, and are irrevocable provided the stated
158conditions are met. This License explicitly affirms your unlimited
159permission to run the unmodified Program. The output from running a
160covered work is covered by this License only if the output, given its
161content, constitutes a covered work. This License acknowledges your
162rights of fair use or other equivalent, as provided by copyright law.
163
164 You may make, run and propagate covered works that you do not
165convey, without conditions so long as your license otherwise remains
166in force. You may convey covered works to others for the sole purpose
167of having them make modifications exclusively for you, or provide you
168with facilities for running those works, provided that you comply with
169the terms of this License in conveying all material for which you do
170not control copyright. Those thus making or running the covered works
171for you must do so exclusively on your behalf, under your direction
172and control, on terms that prohibit them from making any copies of
173your copyrighted material outside their relationship with you.
174
175 Conveying under any other circumstances is permitted solely under
176the conditions stated below. Sublicensing is not allowed; section 10
177makes it unnecessary.
178
179 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
181 No covered work shall be deemed part of an effective technological
182measure under any applicable law fulfilling obligations under article
18311 of the WIPO copyright treaty adopted on 20 December 1996, or
184similar laws prohibiting or restricting circumvention of such
185measures.
186
187 When you convey a covered work, you waive any legal power to forbid
188circumvention of technological measures to the extent such circumvention
189is effected by exercising rights under this License with respect to
190the covered work, and you disclaim any intention to limit operation or
191modification of the work as a means of enforcing, against the work's
192users, your or third parties' legal rights to forbid circumvention of
193technological measures.
194
195 4. Conveying Verbatim Copies.
196
197 You may convey verbatim copies of the Program's source code as you
198receive it, in any medium, provided that you conspicuously and
199appropriately publish on each copy an appropriate copyright notice;
200keep intact all notices stating that this License and any
201non-permissive terms added in accord with section 7 apply to the code;
202keep intact all notices of the absence of any warranty; and give all
203recipients a copy of this License along with the Program.
204
205 You may charge any price or no price for each copy that you convey,
206and you may offer support or warranty protection for a fee.
207
208 5. Conveying Modified Source Versions.
209
210 You may convey a work based on the Program, or the modifications to
211produce it from the Program, in the form of source code under the
212terms of section 4, provided that you also meet all of these conditions:
213
214 a) The work must carry prominent notices stating that you modified
215 it, and giving a relevant date.
216
217 b) The work must carry prominent notices stating that it is
218 released under this License and any conditions added under section
219 7. This requirement modifies the requirement in section 4 to
220 "keep intact all notices".
221
222 c) You must license the entire work, as a whole, under this
223 License to anyone who comes into possession of a copy. This
224 License will therefore apply, along with any applicable section 7
225 additional terms, to the whole of the work, and all its parts,
226 regardless of how they are packaged. This License gives no
227 permission to license the work in any other way, but it does not
228 invalidate such permission if you have separately received it.
229
230 d) If the work has interactive user interfaces, each must display
231 Appropriate Legal Notices; however, if the Program has interactive
232 interfaces that do not display Appropriate Legal Notices, your
233 work need not make them do so.
234
235 A compilation of a covered work with other separate and independent
236works, which are not by their nature extensions of the covered work,
237and which are not combined with it such as to form a larger program,
238in or on a volume of a storage or distribution medium, is called an
239"aggregate" if the compilation and its resulting copyright are not
240used to limit the access or legal rights of the compilation's users
241beyond what the individual works permit. Inclusion of a covered work
242in an aggregate does not cause this License to apply to the other
243parts of the aggregate.
244
245 6. Conveying Non-Source Forms.
246
247 You may convey a covered work in object code form under the terms
248of sections 4 and 5, provided that you also convey the
249machine-readable Corresponding Source under the terms of this License,
250in one of these ways:
251
252 a) Convey the object code in, or embodied in, a physical product
253 (including a physical distribution medium), accompanied by the
254 Corresponding Source fixed on a durable physical medium
255 customarily used for software interchange.
256
257 b) Convey the object code in, or embodied in, a physical product
258 (including a physical distribution medium), accompanied by a
259 written offer, valid for at least three years and valid for as
260 long as you offer spare parts or customer support for that product
261 model, to give anyone who possesses the object code either (1) a
262 copy of the Corresponding Source for all the software in the
263 product that is covered by this License, on a durable physical
264 medium customarily used for software interchange, for a price no
265 more than your reasonable cost of physically performing this
266 conveying of source, or (2) access to copy the
267 Corresponding Source from a network server at no charge.
268
269 c) Convey individual copies of the object code with a copy of the
270 written offer to provide the Corresponding Source. This
271 alternative is allowed only occasionally and noncommercially, and
272 only if you received the object code with such an offer, in accord
273 with subsection 6b.
274
275 d) Convey the object code by offering access from a designated
276 place (gratis or for a charge), and offer equivalent access to the
277 Corresponding Source in the same way through the same place at no
278 further charge. You need not require recipients to copy the
279 Corresponding Source along with the object code. If the place to
280 copy the object code is a network server, the Corresponding Source
281 may be on a different server (operated by you or a third party)
282 that supports equivalent copying facilities, provided you maintain
283 clear directions next to the object code saying where to find the
284 Corresponding Source. Regardless of what server hosts the
285 Corresponding Source, you remain obligated to ensure that it is
286 available for as long as needed to satisfy these requirements.
287
288 e) Convey the object code using peer-to-peer transmission, provided
289 you inform other peers where the object code and Corresponding
290 Source of the work are being offered to the general public at no
291 charge under subsection 6d.
292
293 A separable portion of the object code, whose source code is excluded
294from the Corresponding Source as a System Library, need not be
295included in conveying the object code work.
296
297 A "User Product" is either (1) a "consumer product", which means any
298tangible personal property which is normally used for personal, family,
299or household purposes, or (2) anything designed or sold for incorporation
300into a dwelling. In determining whether a product is a consumer product,
301doubtful cases shall be resolved in favor of coverage. For a particular
302product received by a particular user, "normally used" refers to a
303typical or common use of that class of product, regardless of the status
304of the particular user or of the way in which the particular user
305actually uses, or expects or is expected to use, the product. A product
306is a consumer product regardless of whether the product has substantial
307commercial, industrial or non-consumer uses, unless such uses represent
308the only significant mode of use of the product.
309
310 "Installation Information" for a User Product means any methods,
311procedures, authorization keys, or other information required to install
312and execute modified versions of a covered work in that User Product from
313a modified version of its Corresponding Source. The information must
314suffice to ensure that the continued functioning of the modified object
315code is in no case prevented or interfered with solely because
316modification has been made.
317
318 If you convey an object code work under this section in, or with, or
319specifically for use in, a User Product, and the conveying occurs as
320part of a transaction in which the right of possession and use of the
321User Product is transferred to the recipient in perpetuity or for a
322fixed term (regardless of how the transaction is characterized), the
323Corresponding Source conveyed under this section must be accompanied
324by the Installation Information. But this requirement does not apply
325if neither you nor any third party retains the ability to install
326modified object code on the User Product (for example, the work has
327been installed in ROM).
328
329 The requirement to provide Installation Information does not include a
330requirement to continue to provide support service, warranty, or updates
331for a work that has been modified or installed by the recipient, or for
332the User Product in which it has been modified or installed. Access to a
333network may be denied when the modification itself materially and
334adversely affects the operation of the network or violates the rules and
335protocols for communication across the network.
336
337 Corresponding Source conveyed, and Installation Information provided,
338in accord with this section must be in a format that is publicly
339documented (and with an implementation available to the public in
340source code form), and must require no special password or key for
341unpacking, reading or copying.
342
343 7. Additional Terms.
344
345 "Additional permissions" are terms that supplement the terms of this
346License by making exceptions from one or more of its conditions.
347Additional permissions that are applicable to the entire Program shall
348be treated as though they were included in this License, to the extent
349that they are valid under applicable law. If additional permissions
350apply only to part of the Program, that part may be used separately
351under those permissions, but the entire Program remains governed by
352this License without regard to the additional permissions.
353
354 When you convey a copy of a covered work, you may at your option
355remove any additional permissions from that copy, or from any part of
356it. (Additional permissions may be written to require their own
357removal in certain cases when you modify the work.) You may place
358additional permissions on material, added by you to a covered work,
359for which you have or can give appropriate copyright permission.
360
361 Notwithstanding any other provision of this License, for material you
362add to a covered work, you may (if authorized by the copyright holders of
363that material) supplement the terms of this License with terms:
364
365 a) Disclaiming warranty or limiting liability differently from the
366 terms of sections 15 and 16 of this License; or
367
368 b) Requiring preservation of specified reasonable legal notices or
369 author attributions in that material or in the Appropriate Legal
370 Notices displayed by works containing it; or
371
372 c) Prohibiting misrepresentation of the origin of that material, or
373 requiring that modified versions of such material be marked in
374 reasonable ways as different from the original version; or
375
376 d) Limiting the use for publicity purposes of names of licensors or
377 authors of the material; or
378
379 e) Declining to grant rights under trademark law for use of some
380 trade names, trademarks, or service marks; or
381
382 f) Requiring indemnification of licensors and authors of that
383 material by anyone who conveys the material (or modified versions of
384 it) with contractual assumptions of liability to the recipient, for
385 any liability that these contractual assumptions directly impose on
386 those licensors and authors.
387
388 All other non-permissive additional terms are considered "further
389restrictions" within the meaning of section 10. If the Program as you
390received it, or any part of it, contains a notice stating that it is
391governed by this License along with a term that is a further
392restriction, you may remove that term. If a license document contains
393a further restriction but permits relicensing or conveying under this
394License, you may add to a covered work material governed by the terms
395of that license document, provided that the further restriction does
396not survive such relicensing or conveying.
397
398 If you add terms to a covered work in accord with this section, you
399must place, in the relevant source files, a statement of the
400additional terms that apply to those files, or a notice indicating
401where to find the applicable terms.
402
403 Additional terms, permissive or non-permissive, may be stated in the
404form of a separately written license, or stated as exceptions;
405the above requirements apply either way.
406
407 8. Termination.
408
409 You may not propagate or modify a covered work except as expressly
410provided under this License. Any attempt otherwise to propagate or
411modify it is void, and will automatically terminate your rights under
412this License (including any patent licenses granted under the third
413paragraph of section 11).
414
415 However, if you cease all violation of this License, then your
416license from a particular copyright holder is reinstated (a)
417provisionally, unless and until the copyright holder explicitly and
418finally terminates your license, and (b) permanently, if the copyright
419holder fails to notify you of the violation by some reasonable means
420prior to 60 days after the cessation.
421
422 Moreover, your license from a particular copyright holder is
423reinstated permanently if the copyright holder notifies you of the
424violation by some reasonable means, this is the first time you have
425received notice of violation of this License (for any work) from that
426copyright holder, and you cure the violation prior to 30 days after
427your receipt of the notice.
428
429 Termination of your rights under this section does not terminate the
430licenses of parties who have received copies or rights from you under
431this License. If your rights have been terminated and not permanently
432reinstated, you do not qualify to receive new licenses for the same
433material under section 10.
434
435 9. Acceptance Not Required for Having Copies.
436
437 You are not required to accept this License in order to receive or
438run a copy of the Program. Ancillary propagation of a covered work
439occurring solely as a consequence of using peer-to-peer transmission
440to receive a copy likewise does not require acceptance. However,
441nothing other than this License grants you permission to propagate or
442modify any covered work. These actions infringe copyright if you do
443not accept this License. Therefore, by modifying or propagating a
444covered work, you indicate your acceptance of this License to do so.
445
446 10. Automatic Licensing of Downstream Recipients.
447
448 Each time you convey a covered work, the recipient automatically
449receives a license from the original licensors, to run, modify and
450propagate that work, subject to this License. You are not responsible
451for enforcing compliance by third parties with this License.
452
453 An "entity transaction" is a transaction transferring control of an
454organization, or substantially all assets of one, or subdividing an
455organization, or merging organizations. If propagation of a covered
456work results from an entity transaction, each party to that
457transaction who receives a copy of the work also receives whatever
458licenses to the work the party's predecessor in interest had or could
459give under the previous paragraph, plus a right to possession of the
460Corresponding Source of the work from the predecessor in interest, if
461the predecessor has it or can get it with reasonable efforts.
462
463 You may not impose any further restrictions on the exercise of the
464rights granted or affirmed under this License. For example, you may
465not impose a license fee, royalty, or other charge for exercise of
466rights granted under this License, and you may not initiate litigation
467(including a cross-claim or counterclaim in a lawsuit) alleging that
468any patent claim is infringed by making, using, selling, offering for
469sale, or importing the Program or any portion of it.
470
471 11. Patents.
472
473 A "contributor" is a copyright holder who authorizes use under this
474License of the Program or a work on which the Program is based. The
475work thus licensed is called the contributor's "contributor version".
476
477 A contributor's "essential patent claims" are all patent claims
478owned or controlled by the contributor, whether already acquired or
479hereafter acquired, that would be infringed by some manner, permitted
480by this License, of making, using, or selling its contributor version,
481but do not include claims that would be infringed only as a
482consequence of further modification of the contributor version. For
483purposes of this definition, "control" includes the right to grant
484patent sublicenses in a manner consistent with the requirements of
485this License.
486
487 Each contributor grants you a non-exclusive, worldwide, royalty-free
488patent license under the contributor's essential patent claims, to
489make, use, sell, offer for sale, import and otherwise run, modify and
490propagate the contents of its contributor version.
491
492 In the following three paragraphs, a "patent license" is any express
493agreement or commitment, however denominated, not to enforce a patent
494(such as an express permission to practice a patent or covenant not to
495sue for patent infringement). To "grant" such a patent license to a
496party means to make such an agreement or commitment not to enforce a
497patent against the party.
498
499 If you convey a covered work, knowingly relying on a patent license,
500and the Corresponding Source of the work is not available for anyone
501to copy, free of charge and under the terms of this License, through a
502publicly available network server or other readily accessible means,
503then you must either (1) cause the Corresponding Source to be so
504available, or (2) arrange to deprive yourself of the benefit of the
505patent license for this particular work, or (3) arrange, in a manner
506consistent with the requirements of this License, to extend the patent
507license to downstream recipients. "Knowingly relying" means you have
508actual knowledge that, but for the patent license, your conveying the
509covered work in a country, or your recipient's use of the covered work
510in a country, would infringe one or more identifiable patents in that
511country that you have reason to believe are valid.
512
513 If, pursuant to or in connection with a single transaction or
514arrangement, you convey, or propagate by procuring conveyance of, a
515covered work, and grant a patent license to some of the parties
516receiving the covered work authorizing them to use, propagate, modify
517or convey a specific copy of the covered work, then the patent license
518you grant is automatically extended to all recipients of the covered
519work and works based on it.
520
521 A patent license is "discriminatory" if it does not include within
522the scope of its coverage, prohibits the exercise of, or is
523conditioned on the non-exercise of one or more of the rights that are
524specifically granted under this License. You may not convey a covered
525work if you are a party to an arrangement with a third party that is
526in the business of distributing software, under which you make payment
527to the third party based on the extent of your activity of conveying
528the work, and under which the third party grants, to any of the
529parties who would receive the covered work from you, a discriminatory
530patent license (a) in connection with copies of the covered work
531conveyed by you (or copies made from those copies), or (b) primarily
532for and in connection with specific products or compilations that
533contain the covered work, unless you entered into that arrangement,
534or that patent license was granted, prior to 28 March 2007.
535
536 Nothing in this License shall be construed as excluding or limiting
537any implied license or other defenses to infringement that may
538otherwise be available to you under applicable patent law.
539
540 12. No Surrender of Others' Freedom.
541
542 If conditions are imposed on you (whether by court order, agreement or
543otherwise) that contradict the conditions of this License, they do not
544excuse you from the conditions of this License. If you cannot convey a
545covered work so as to satisfy simultaneously your obligations under this
546License and any other pertinent obligations, then as a consequence you may
547not convey it at all. For example, if you agree to terms that obligate you
548to collect a royalty for further conveying from those to whom you convey
549the Program, the only way you could satisfy both those terms and this
550License would be to refrain entirely from conveying the Program.
551
552 13. Use with the GNU Affero General Public License.
553
554 Notwithstanding any other provision of this License, you have
555permission to link or combine any covered work with a work licensed
556under version 3 of the GNU Affero General Public License into a single
557combined work, and to convey the resulting work. The terms of this
558License will continue to apply to the part which is the covered work,
559but the special requirements of the GNU Affero General Public License,
560section 13, concerning interaction through a network will apply to the
561combination as such.
562
563 14. Revised Versions of this License.
564
565 The Free Software Foundation may publish revised and/or new versions of
566the GNU General Public License from time to time. Such new versions will
567be similar in spirit to the present version, but may differ in detail to
568address new problems or concerns.
569
570 Each version is given a distinguishing version number. If the
571Program specifies that a certain numbered version of the GNU General
572Public License "or any later version" applies to it, you have the
573option of following the terms and conditions either of that numbered
574version or of any later version published by the Free Software
575Foundation. If the Program does not specify a version number of the
576GNU General Public License, you may choose any version ever published
577by the Free Software Foundation.
578
579 If the Program specifies that a proxy can decide which future
580versions of the GNU General Public License can be used, that proxy's
581public statement of acceptance of a version permanently authorizes you
582to choose that version for the Program.
583
584 Later license versions may give you additional or different
585permissions. However, no additional obligations are imposed on any
586author or copyright holder as a result of your choosing to follow a
587later version.
588
589 15. Disclaimer of Warranty.
590
591 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
600 16. Limitation of Liability.
601
602 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610SUCH DAMAGES.
611
612 17. Interpretation of Sections 15 and 16.
613
614 If the disclaimer of warranty and limitation of liability provided
615above cannot be given local legal effect according to their terms,
616reviewing courts shall apply local law that most closely approximates
617an absolute waiver of all civil liability in connection with the
618Program, unless a warranty or assumption of liability accompanies a
619copy of the Program in return for a fee.
620
621 END OF TERMS AND CONDITIONS
622
623 How to Apply These Terms to Your New Programs
624
625 If you develop a new program, and you want it to be of the greatest
626possible use to the public, the best way to achieve this is to make it
627free software which everyone can redistribute and change under these terms.
628
629 To do so, attach the following notices to the program. It is safest
630to attach them to the start of each source file to most effectively
631state the exclusion of warranty; and each file should have at least
632the "copyright" line and a pointer to where the full notice is found.
633
634 <one line to give the program's name and a brief idea of what it does.>
635 Copyright (C) <year> <name of author>
636
637 This program is free software: you can redistribute it and/or modify
638 it under the terms of the GNU General Public License as published by
639 the Free Software Foundation, either version 3 of the License, or
640 (at your option) any later version.
641
642 This program is distributed in the hope that it will be useful,
643 but WITHOUT ANY WARRANTY; without even the implied warranty of
644 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 GNU General Public License for more details.
646
647 You should have received a copy of the GNU General Public License
648 along with this program. If not, see <http://www.gnu.org/licenses/>.
649
650Also add information on how to contact you by electronic and paper mail.
651
652 If the program does terminal interaction, make it output a short
653notice like this when it starts in an interactive mode:
654
655 <program> Copyright (C) <year> <name of author>
656 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 This is free software, and you are welcome to redistribute it
658 under certain conditions; type `show c' for details.
659
660The hypothetical commands `show w' and `show c' should show the appropriate
661parts of the General Public License. Of course, your program's commands
662might be different; for a GUI interface, you would use an "about box".
663
664 You should also get your employer (if you work as a programmer) or school,
665if any, to sign a "copyright disclaimer" for the program, if necessary.
666For more information on this, and how to apply and follow the GNU GPL, see
667<http://www.gnu.org/licenses/>.
668
669 The GNU General Public License does not permit incorporating your program
670into proprietary programs. If your program is a subroutine library, you
671may consider it more useful to permit linking proprietary applications with
672the library. If this is what you want to do, use the GNU Lesser General
673Public License instead of this License. But first, please read
674<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/contrib/SDL-3.2.8/src/hidapi/LICENSE-orig.txt b/contrib/SDL-3.2.8/src/hidapi/LICENSE-orig.txt
new file mode 100644
index 0000000..e3f3380
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/LICENSE-orig.txt
@@ -0,0 +1,9 @@
1 HIDAPI - Multi-Platform library for
2 communication with HID devices.
3
4 Copyright 2009, Alan Ott, Signal 11 Software.
5 All Rights Reserved.
6
7 This software may be used by anyone for any reason so
8 long as the copyright notice in the source files
9 remains intact.
diff --git a/contrib/SDL-3.2.8/src/hidapi/LICENSE.txt b/contrib/SDL-3.2.8/src/hidapi/LICENSE.txt
new file mode 100644
index 0000000..e1676d4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/LICENSE.txt
@@ -0,0 +1,13 @@
1HIDAPI can be used under one of three licenses.
2
31. The GNU General Public License, version 3.0, in LICENSE-gpl3.txt
42. A BSD-Style License, in LICENSE-bsd.txt.
53. The more liberal original HIDAPI license. LICENSE-orig.txt
6
7The license chosen is at the discretion of the user of HIDAPI. For example:
81. An author of GPL software would likely use HIDAPI under the terms of the
9GPL.
10
112. An author of commercial closed-source software would likely use HIDAPI
12under the terms of the BSD-style license or the original HIDAPI license.
13
diff --git a/contrib/SDL-3.2.8/src/hidapi/Makefile.am b/contrib/SDL-3.2.8/src/hidapi/Makefile.am
new file mode 100644
index 0000000..00bcb73
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/Makefile.am
@@ -0,0 +1,85 @@
1
2ACLOCAL_AMFLAGS = -I m4
3
4if OS_FREEBSD
5pkgconfigdir=$(prefix)/libdata/pkgconfig
6else
7pkgconfigdir=$(libdir)/pkgconfig
8endif
9
10if OS_LINUX
11pkgconfig_DATA=pc/hidapi-hidraw.pc pc/hidapi-libusb.pc
12else
13pkgconfig_DATA=pc/hidapi.pc
14endif
15
16SUBDIRS=
17
18if OS_LINUX
19SUBDIRS += linux libusb
20endif
21
22if OS_DARWIN
23SUBDIRS += mac
24endif
25
26if OS_FREEBSD
27SUBDIRS += libusb
28endif
29
30if OS_KFREEBSD
31SUBDIRS += libusb
32endif
33
34if OS_HAIKU
35SUBDIRS += libusb
36endif
37
38if OS_WINDOWS
39SUBDIRS += windows
40endif
41
42SUBDIRS += hidtest
43
44if BUILD_TESTGUI
45SUBDIRS += testgui
46endif
47
48EXTRA_DIST = udev doxygen
49
50dist_doc_DATA = \
51 README.md \
52 AUTHORS.txt \
53 LICENSE-bsd.txt \
54 LICENSE-gpl3.txt \
55 LICENSE-orig.txt \
56 LICENSE.txt
57
58SCMCLEAN_TARGETS= \
59 aclocal.m4 \
60 config.guess \
61 config.sub \
62 configure \
63 config.h.in \
64 depcomp \
65 install-sh \
66 ltmain.sh \
67 missing \
68 mac/Makefile.in \
69 testgui/Makefile.in \
70 libusb/Makefile.in \
71 Makefile.in \
72 linux/Makefile.in \
73 windows/Makefile.in \
74 m4/libtool.m4 \
75 m4/lt~obsolete.m4 \
76 m4/ltoptions.m4 \
77 m4/ltsugar.m4 \
78 m4/ltversion.m4
79
80SCMCLEAN_DIR_TARGETS = \
81 autom4te.cache
82
83scm-clean: distclean
84 rm -f $(SCMCLEAN_TARGETS)
85 rm -Rf $(SCMCLEAN_DIR_TARGETS)
diff --git a/contrib/SDL-3.2.8/src/hidapi/README.md b/contrib/SDL-3.2.8/src/hidapi/README.md
new file mode 100644
index 0000000..257b9f3
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/README.md
@@ -0,0 +1,196 @@
1## HIDAPI library for Windows, Linux, FreeBSD and macOS
2
3| CI instance | Status |
4|----------------------|--------|
5| `Linux/macOS/Windows (master)` | [![GitHub Builds](https://github.com/libusb/hidapi/workflows/GitHub%20Builds/badge.svg?branch=master)](https://github.com/libusb/hidapi/actions/workflows/builds.yml?query=branch%3Amaster) |
6| `Windows (master)` | [![Build status](https://ci.appveyor.com/api/projects/status/xfmr5fo8w0re8ded/branch/master?svg=true)](https://ci.appveyor.com/project/libusb/hidapi/branch/master) |
7| `BSD, last build (branch/PR)` | [![builds.sr.ht status](https://builds.sr.ht/~z3ntu/hidapi.svg)](https://builds.sr.ht/~z3ntu/hidapi) |
8| `Coverity Scan (last)` | ![Coverity Scan](https://scan.coverity.com/projects/583/badge.svg) |
9
10HIDAPI is a multi-platform library which allows an application to interface
11with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and macOS.
12HIDAPI can be either built as a shared library (`.so`, `.dll` or `.dylib`) or
13can be embedded directly into a target application by adding a _single source_
14file (per platform) and a single header.<br>
15See [remarks](BUILD.md#embedding-hidapi-directly-into-your-source-tree) on embedding _directly_ into your build system.
16
17HIDAPI library was originally developed by Alan Ott ([signal11](https://github.com/signal11)).
18
19It was moved to [libusb/hidapi](https://github.com/libusb/hidapi) on June 4th, 2019, in order to merge important bugfixes and continue development of the library.
20
21## Table of Contents
22
23* [About](#about)
24 * [Test GUI](#test-gui)
25 * [Console Test App](#console-test-app)
26* [What Does the API Look Like?](#what-does-the-api-look-like)
27* [License](#license)
28* [Installing HIDAPI](#installing-hidapi)
29* [Build from Source](#build-from-source)
30
31
32## About
33
34### HIDAPI has four back-ends:
35* Windows (using `hid.dll`)
36* Linux/hidraw (using the Kernel's hidraw driver)
37* libusb (using libusb-1.0 - Linux/BSD/other UNIX-like systems)
38* macOS (using IOHidManager)
39
40On Linux, either the hidraw or the libusb back-end can be used. There are
41tradeoffs, and the functionality supported is slightly different. Both are
42built by default. It is up to the application linking to hidapi to choose
43the backend at link time by linking to either `libhidapi-libusb` or
44`libhidapi-hidraw`.
45
46Note that you will need to install an udev rule file with your application
47for unprivileged users to be able to access HID devices with hidapi. Refer
48to the [69-hid.rules](udev/69-hid.rules) file in the `udev` directory
49for an example.
50
51#### __Linux/hidraw__ (`linux/hid.c`):
52
53This back-end uses the hidraw interface in the Linux kernel, and supports
54both USB and Bluetooth HID devices. It requires kernel version at least 2.6.39
55to build. In addition, it will only communicate with devices which have hidraw
56nodes associated with them.
57Keyboards, mice, and some other devices which are blacklisted from having
58hidraw nodes will not work. Fortunately, for nearly all the uses of hidraw,
59this is not a problem.
60
61#### __Linux/FreeBSD/libusb__ (`libusb/hid.c`):
62
63This back-end uses libusb-1.0 to communicate directly to a USB device. This
64back-end will of course not work with Bluetooth devices.
65
66### Test GUI
67
68HIDAPI also comes with a Test GUI. The Test GUI is cross-platform and uses
69Fox Toolkit <http://www.fox-toolkit.org>. It will build on every platform
70which HIDAPI supports. Since it relies on a 3rd party library, building it
71is optional but it is useful when debugging hardware.
72
73NOTE: Test GUI based on Fox Toolkit is not actively developed nor supported
74by HIDAPI team. It is kept as a historical artifact. It may even work sometime
75or on some platforms, but it is not going to get any new features or bugfixes.
76
77Instructions for installing Fox-Toolkit on each platform is not provided.
78Make sure to use Fox-Toolkit v1.6 if you choose to use it.
79
80### Console Test App
81
82If you want to play around with your HID device before starting
83any development with HIDAPI and using a GUI app is not an option for you, you may try [`hidapitester`](https://github.com/todbot/hidapitester).
84
85This app has a console interface for most of the features supported
86by HIDAPI library.
87
88## What Does the API Look Like?
89
90The API provides the most commonly used HID functions including sending
91and receiving of input, output, and feature reports. The sample program,
92which communicates with a heavily hacked up version of the Microchip USB
93Generic HID sample looks like this (with error checking removed for
94simplicity):
95
96**Warning: Only run the code you understand, and only when it conforms to the
97device spec. Writing data (`hid_write`) at random to your HID devices can break them.**
98
99```c
100#include <stdio.h> // printf
101#include <wchar.h> // wchar_t
102
103#include <hidapi.h>
104
105#define MAX_STR 255
106
107int main(int argc, char* argv[])
108{
109 int res;
110 unsigned char buf[65];
111 wchar_t wstr[MAX_STR];
112 hid_device *handle;
113 int i;
114
115 // Initialize the hidapi library
116 res = hid_init();
117
118 // Open the device using the VID, PID,
119 // and optionally the Serial number.
120 handle = hid_open(0x4d8, 0x3f, NULL);
121 if (!handle) {
122 printf("Unable to open device\n");
123 hid_exit();
124 return 1;
125 }
126
127 // Read the Manufacturer String
128 res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
129 printf("Manufacturer String: %ls\n", wstr);
130
131 // Read the Product String
132 res = hid_get_product_string(handle, wstr, MAX_STR);
133 printf("Product String: %ls\n", wstr);
134
135 // Read the Serial Number String
136 res = hid_get_serial_number_string(handle, wstr, MAX_STR);
137 printf("Serial Number String: (%d) %ls\n", wstr[0], wstr);
138
139 // Read Indexed String 1
140 res = hid_get_indexed_string(handle, 1, wstr, MAX_STR);
141 printf("Indexed String 1: %ls\n", wstr);
142
143 // Toggle LED (cmd 0x80). The first byte is the report number (0x0).
144 buf[0] = 0x0;
145 buf[1] = 0x80;
146 res = hid_write(handle, buf, 65);
147
148 // Request state (cmd 0x81). The first byte is the report number (0x0).
149 buf[0] = 0x0;
150 buf[1] = 0x81;
151 res = hid_write(handle, buf, 65);
152
153 // Read requested state
154 res = hid_read(handle, buf, 65);
155
156 // Print out the returned buffer.
157 for (i = 0; i < 4; i++)
158 printf("buf[%d]: %d\n", i, buf[i]);
159
160 // Close the device
161 hid_close(handle);
162
163 // Finalize the hidapi library
164 res = hid_exit();
165
166 return 0;
167}
168```
169
170You can also use [hidtest/test.c](hidtest/test.c)
171as a starting point for your applications.
172
173
174## License
175
176HIDAPI may be used by one of three licenses as outlined in [LICENSE.txt](LICENSE.txt).
177
178## Installing HIDAPI
179
180If you want to build your own application that uses HID devices with HIDAPI,
181you need to get HIDAPI development package.
182
183Depending on what your development environment is, HIDAPI likely to be provided
184by your package manager.
185
186For instance on Ubuntu, HIDAPI is available via APT:
187```sh
188sudo apt install libhidapi-dev
189```
190
191HIDAPI package name for other systems/package managers may differ.
192Check the documentation/package list of your package manager.
193
194## Build from Source
195
196Check [BUILD.md](BUILD.md) for details.
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi.c b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi.c
new file mode 100644
index 0000000..b14b75e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi.c
@@ -0,0 +1,1750 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/* Original hybrid wrapper for Linux by Valve Software. Their original notes:
23 *
24 * The libusb version doesn't support Bluetooth, but not all Linux
25 * distributions allow access to /dev/hidraw*
26 *
27 * This merges the two, at a small performance cost, until distributions
28 * have granted access to /dev/hidraw*
29 */
30
31#include "SDL_internal.h"
32
33#include "SDL_hidapi_c.h"
34#include "../joystick/usb_ids.h"
35#include "../SDL_hints_c.h"
36
37// Initial type declarations
38#define HID_API_NO_EXPORT_DEFINE // do not export hidapi procedures
39#include "hidapi/hidapi.h"
40
41#ifndef SDL_HIDAPI_DISABLED
42
43#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
44#include "../core/windows/SDL_windows.h"
45#endif
46
47#ifdef SDL_PLATFORM_MACOS
48#include <CoreFoundation/CoreFoundation.h>
49#include <mach/mach.h>
50#include <IOKit/IOKitLib.h>
51#include <IOKit/hid/IOHIDDevice.h>
52#include <IOKit/usb/USBSpec.h>
53#include <AvailabilityMacros.h>
54// Things named "Master" were renamed to "Main" in macOS 12.0's SDK.
55#if MAC_OS_X_VERSION_MIN_REQUIRED < 120000
56#define kIOMainPortDefault kIOMasterPortDefault
57#endif
58#endif
59
60#include "../core/linux/SDL_udev.h"
61#ifdef SDL_USE_LIBUDEV
62#include <poll.h>
63#endif
64
65#ifdef HAVE_INOTIFY
66#include <string.h> // strerror
67#include <errno.h> // errno
68#include <fcntl.h>
69#include <limits.h> // For the definition of NAME_MAX
70#include <sys/inotify.h>
71#endif
72
73#if defined(SDL_USE_LIBUDEV) || defined(HAVE_INOTIFY)
74#include <unistd.h>
75#endif
76
77#ifdef SDL_USE_LIBUDEV
78typedef enum
79{
80 ENUMERATION_UNSET,
81 ENUMERATION_LIBUDEV,
82 ENUMERATION_FALLBACK
83} LinuxEnumerationMethod;
84
85static LinuxEnumerationMethod linux_enumeration_method = ENUMERATION_UNSET;
86#endif
87
88#ifdef HAVE_INOTIFY
89static int inotify_fd = -1;
90#endif
91
92#ifdef SDL_USE_LIBUDEV
93static const SDL_UDEV_Symbols *usyms = NULL;
94#endif
95
96static struct
97{
98 bool m_bInitialized;
99 Uint32 m_unDeviceChangeCounter;
100 bool m_bCanGetNotifications;
101 Uint64 m_unLastDetect;
102
103#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
104 SDL_ThreadID m_nThreadID;
105 WNDCLASSEXA m_wndClass;
106 HWND m_hwndMsg;
107 HDEVNOTIFY m_hNotify;
108 double m_flLastWin32MessageCheck;
109#endif
110
111#ifdef SDL_PLATFORM_MACOS
112 IONotificationPortRef m_notificationPort;
113 mach_port_t m_notificationMach;
114#endif
115
116#ifdef SDL_USE_LIBUDEV
117 struct udev *m_pUdev;
118 struct udev_monitor *m_pUdevMonitor;
119 int m_nUdevFd;
120#endif
121} SDL_HIDAPI_discovery;
122
123#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
124struct _DEV_BROADCAST_HDR
125{
126 DWORD dbch_size;
127 DWORD dbch_devicetype;
128 DWORD dbch_reserved;
129};
130
131typedef struct _DEV_BROADCAST_DEVICEINTERFACE_A
132{
133 DWORD dbcc_size;
134 DWORD dbcc_devicetype;
135 DWORD dbcc_reserved;
136 GUID dbcc_classguid;
137 char dbcc_name[1];
138} DEV_BROADCAST_DEVICEINTERFACE_A, *PDEV_BROADCAST_DEVICEINTERFACE_A;
139
140typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR;
141#define DBT_DEVICEARRIVAL 0x8000 // system detected a new device
142#define DBT_DEVICEREMOVECOMPLETE 0x8004 // device was removed from the system
143#define DBT_DEVTYP_DEVICEINTERFACE 0x00000005 // device interface class
144#define DBT_DEVNODES_CHANGED 0x0007
145#define DBT_CONFIGCHANGED 0x0018
146#define DBT_DEVICETYPESPECIFIC 0x8005 // type specific event
147#define DBT_DEVINSTSTARTED 0x8008 // device installed and started
148
149#include <initguid.h>
150DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
151
152static LRESULT CALLBACK ControllerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
153{
154 switch (message) {
155 case WM_DEVICECHANGE:
156 switch (wParam) {
157 case DBT_DEVICEARRIVAL:
158 case DBT_DEVICEREMOVECOMPLETE:
159 if (((DEV_BROADCAST_HDR *)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
160 ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
161 }
162 break;
163 }
164 return TRUE;
165 }
166
167 return DefWindowProc(hwnd, message, wParam, lParam);
168}
169#endif // defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
170
171#ifdef SDL_PLATFORM_MACOS
172static void CallbackIOServiceFunc(void *context, io_iterator_t portIterator)
173{
174 // Must drain the iterator, or we won't receive new notifications
175 io_object_t entry;
176 while ((entry = IOIteratorNext(portIterator)) != 0) {
177 IOObjectRelease(entry);
178 ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
179 }
180}
181#endif // SDL_PLATFORM_MACOS
182
183#ifdef HAVE_INOTIFY
184#ifdef HAVE_INOTIFY_INIT1
185static int SDL_inotify_init1(void)
186{
187 return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
188}
189#else
190static int SDL_inotify_init1(void)
191{
192 int fd = inotify_init();
193 if (fd < 0) {
194 return -1;
195 }
196 fcntl(fd, F_SETFL, O_NONBLOCK);
197 fcntl(fd, F_SETFD, FD_CLOEXEC);
198 return fd;
199}
200#endif
201
202static int StrHasPrefix(const char *string, const char *prefix)
203{
204 return SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0;
205}
206
207static int StrIsInteger(const char *string)
208{
209 const char *p;
210
211 if (*string == '\0') {
212 return 0;
213 }
214
215 for (p = string; *p != '\0'; p++) {
216 if (*p < '0' || *p > '9') {
217 return 0;
218 }
219 }
220
221 return 1;
222}
223#endif // HAVE_INOTIFY
224
225static void HIDAPI_InitializeDiscovery(void)
226{
227 SDL_HIDAPI_discovery.m_bInitialized = true;
228 SDL_HIDAPI_discovery.m_unDeviceChangeCounter = 1;
229 SDL_HIDAPI_discovery.m_bCanGetNotifications = false;
230 SDL_HIDAPI_discovery.m_unLastDetect = 0;
231
232#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
233 SDL_HIDAPI_discovery.m_nThreadID = SDL_GetCurrentThreadID();
234
235 SDL_zero(SDL_HIDAPI_discovery.m_wndClass);
236 SDL_HIDAPI_discovery.m_wndClass.hInstance = GetModuleHandle(NULL);
237 SDL_HIDAPI_discovery.m_wndClass.lpszClassName = "SDL_HIDAPI_DEVICE_DETECTION";
238 SDL_HIDAPI_discovery.m_wndClass.lpfnWndProc = ControllerWndProc; // This function is called by windows
239 SDL_HIDAPI_discovery.m_wndClass.cbSize = sizeof(WNDCLASSEX);
240
241 RegisterClassExA(&SDL_HIDAPI_discovery.m_wndClass);
242 SDL_HIDAPI_discovery.m_hwndMsg = CreateWindowExA(0, "SDL_HIDAPI_DEVICE_DETECTION", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
243
244 {
245 DEV_BROADCAST_DEVICEINTERFACE_A devBroadcast;
246
247 SDL_zero(devBroadcast);
248 devBroadcast.dbcc_size = sizeof(devBroadcast);
249 devBroadcast.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
250 devBroadcast.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
251
252 /* DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is important, makes GUID_DEVINTERFACE_USB_DEVICE ignored,
253 * but that seems to be necessary to get a notice after each individual usb input device actually
254 * installs, rather than just as the composite device is seen.
255 */
256 SDL_HIDAPI_discovery.m_hNotify = RegisterDeviceNotification(SDL_HIDAPI_discovery.m_hwndMsg, &devBroadcast, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
257 SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_hNotify != 0);
258 }
259#endif // defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
260
261#ifdef SDL_PLATFORM_MACOS
262 SDL_HIDAPI_discovery.m_notificationPort = IONotificationPortCreate(kIOMainPortDefault);
263 if (SDL_HIDAPI_discovery.m_notificationPort) {
264 {
265 io_iterator_t portIterator = 0;
266 io_object_t entry;
267 IOReturn result = IOServiceAddMatchingNotification(
268 SDL_HIDAPI_discovery.m_notificationPort,
269 kIOFirstMatchNotification,
270 IOServiceMatching(kIOHIDDeviceKey),
271 CallbackIOServiceFunc, NULL, &portIterator);
272
273 if (result == 0) {
274 // Must drain the existing iterator, or we won't receive new notifications
275 while ((entry = IOIteratorNext(portIterator)) != 0) {
276 IOObjectRelease(entry);
277 }
278 } else {
279 IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
280 SDL_HIDAPI_discovery.m_notificationPort = nil;
281 }
282 }
283 {
284 io_iterator_t portIterator = 0;
285 io_object_t entry;
286 IOReturn result = IOServiceAddMatchingNotification(
287 SDL_HIDAPI_discovery.m_notificationPort,
288 kIOTerminatedNotification,
289 IOServiceMatching(kIOHIDDeviceKey),
290 CallbackIOServiceFunc, NULL, &portIterator);
291
292 if (result == 0) {
293 // Must drain the existing iterator, or we won't receive new notifications
294 while ((entry = IOIteratorNext(portIterator)) != 0) {
295 IOObjectRelease(entry);
296 }
297 } else {
298 IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
299 SDL_HIDAPI_discovery.m_notificationPort = nil;
300 }
301 }
302 }
303
304 SDL_HIDAPI_discovery.m_notificationMach = MACH_PORT_NULL;
305 if (SDL_HIDAPI_discovery.m_notificationPort) {
306 SDL_HIDAPI_discovery.m_notificationMach = IONotificationPortGetMachPort(SDL_HIDAPI_discovery.m_notificationPort);
307 }
308
309 SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_notificationMach != MACH_PORT_NULL);
310
311#endif // SDL_PLATFORM_MACOS
312
313#ifdef SDL_USE_LIBUDEV
314 if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
315 SDL_HIDAPI_discovery.m_pUdev = NULL;
316 SDL_HIDAPI_discovery.m_pUdevMonitor = NULL;
317 SDL_HIDAPI_discovery.m_nUdevFd = -1;
318
319 usyms = SDL_UDEV_GetUdevSyms();
320 if (usyms != NULL) {
321 SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new();
322 if (SDL_HIDAPI_discovery.m_pUdev != NULL) {
323 SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev");
324 if (SDL_HIDAPI_discovery.m_pUdevMonitor != NULL) {
325 usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor);
326 SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor);
327 SDL_HIDAPI_discovery.m_bCanGetNotifications = true;
328 }
329 }
330 }
331 } else
332#endif // SDL_USE_LIBUDEV
333 {
334#ifdef HAVE_INOTIFY
335 inotify_fd = SDL_inotify_init1();
336
337 if (inotify_fd < 0) {
338 SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
339 "Unable to initialize inotify, falling back to polling: %s",
340 strerror(errno));
341 return;
342 }
343
344 /* We need to watch for attribute changes in addition to
345 * creation, because when a device is first created, it has
346 * permissions that we can't read. When udev chmods it to
347 * something that we maybe *can* read, we'll get an
348 * IN_ATTRIB event to tell us. */
349 if (inotify_add_watch(inotify_fd, "/dev",
350 IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) {
351 close(inotify_fd);
352 inotify_fd = -1;
353 SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
354 "Unable to add inotify watch, falling back to polling: %s",
355 strerror(errno));
356 return;
357 }
358
359 SDL_HIDAPI_discovery.m_bCanGetNotifications = true;
360#endif // HAVE_INOTIFY
361 }
362}
363
364static void HIDAPI_UpdateDiscovery(void)
365{
366 if (!SDL_HIDAPI_discovery.m_bInitialized) {
367 HIDAPI_InitializeDiscovery();
368 }
369
370 if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) {
371 const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; // Update every 3 seconds
372 Uint64 now = SDL_GetTicks();
373 if (!SDL_HIDAPI_discovery.m_unLastDetect || now >= (SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) {
374 ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
375 SDL_HIDAPI_discovery.m_unLastDetect = now;
376 }
377 return;
378 }
379
380#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
381#if 0 // just let the usual SDL_PumpEvents loop dispatch these, fixing bug 4286. --ryan.
382 // We'll only get messages on the same thread that created the window
383 if (SDL_GetCurrentThreadID() == SDL_HIDAPI_discovery.m_nThreadID) {
384 MSG msg;
385 while (PeekMessage(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0, PM_NOREMOVE)) {
386 if (GetMessageA(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0) != 0) {
387 TranslateMessage(&msg);
388 DispatchMessage(&msg);
389 }
390 }
391 }
392#endif
393#endif // defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
394
395#ifdef SDL_PLATFORM_MACOS
396 if (SDL_HIDAPI_discovery.m_notificationPort) {
397 struct
398 {
399 mach_msg_header_t hdr;
400 char payload[4096];
401 } msg;
402 while (mach_msg(&msg.hdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), SDL_HIDAPI_discovery.m_notificationMach, 0, MACH_PORT_NULL) == KERN_SUCCESS) {
403 IODispatchCalloutFromMessage(NULL, &msg.hdr, SDL_HIDAPI_discovery.m_notificationPort);
404 }
405 }
406#endif
407
408#ifdef SDL_USE_LIBUDEV
409 if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
410 if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) {
411 /* Drain all notification events.
412 * We don't expect a lot of device notifications so just
413 * do a new discovery on any kind or number of notifications.
414 * This could be made more restrictive if necessary.
415 */
416 for (;;) {
417 struct pollfd PollUdev;
418 struct udev_device *pUdevDevice;
419
420 PollUdev.fd = SDL_HIDAPI_discovery.m_nUdevFd;
421 PollUdev.events = POLLIN;
422 if (poll(&PollUdev, 1, 0) != 1) {
423 break;
424 }
425
426 pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor);
427 if (pUdevDevice) {
428 const char *action = NULL;
429 action = usyms->udev_device_get_action(pUdevDevice);
430 if (action == NULL || SDL_strcmp(action, "add") == 0 || SDL_strcmp(action, "remove") == 0) {
431 ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
432 }
433 usyms->udev_device_unref(pUdevDevice);
434 }
435 }
436 }
437 } else
438#endif // SDL_USE_LIBUDEV
439 {
440#ifdef HAVE_INOTIFY
441 if (inotify_fd >= 0) {
442 union
443 {
444 struct inotify_event event;
445 char storage[4096];
446 char enough_for_inotify[sizeof(struct inotify_event) + NAME_MAX + 1];
447 } buf;
448 ssize_t bytes;
449 size_t remain = 0;
450 size_t len;
451
452 bytes = read(inotify_fd, &buf, sizeof(buf));
453
454 if (bytes > 0) {
455 remain = (size_t)bytes;
456 }
457
458 while (remain > 0) {
459 if (buf.event.len > 0) {
460 if (StrHasPrefix(buf.event.name, "hidraw") &&
461 StrIsInteger(buf.event.name + SDL_strlen("hidraw"))) {
462 ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
463 /* We found an hidraw change. We still continue to
464 * drain the inotify fd to avoid leaving old
465 * notifications in the queue. */
466 }
467 }
468
469 len = sizeof(struct inotify_event) + buf.event.len;
470 remain -= len;
471
472 if (remain != 0) {
473 SDL_memmove(&buf.storage[0], &buf.storage[len], remain);
474 }
475 }
476 }
477#endif // HAVE_INOTIFY
478 }
479}
480
481static void HIDAPI_ShutdownDiscovery(void)
482{
483 if (!SDL_HIDAPI_discovery.m_bInitialized) {
484 return;
485 }
486
487#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
488 if (SDL_HIDAPI_discovery.m_hNotify) {
489 UnregisterDeviceNotification(SDL_HIDAPI_discovery.m_hNotify);
490 }
491
492 if (SDL_HIDAPI_discovery.m_hwndMsg) {
493 DestroyWindow(SDL_HIDAPI_discovery.m_hwndMsg);
494 }
495
496 UnregisterClassA(SDL_HIDAPI_discovery.m_wndClass.lpszClassName, SDL_HIDAPI_discovery.m_wndClass.hInstance);
497#endif
498
499#ifdef SDL_PLATFORM_MACOS
500 if (SDL_HIDAPI_discovery.m_notificationPort) {
501 IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
502 }
503#endif
504
505#ifdef SDL_USE_LIBUDEV
506 if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
507 if (usyms) {
508 if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
509 usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
510 }
511 if (SDL_HIDAPI_discovery.m_pUdev) {
512 usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev);
513 }
514 SDL_UDEV_ReleaseUdevSyms();
515 usyms = NULL;
516 }
517 } else
518#endif // SDL_USE_LIBUDEV
519 {
520#ifdef HAVE_INOTIFY
521 if (inotify_fd >= 0) {
522 close(inotify_fd);
523 inotify_fd = -1;
524 }
525#endif
526 }
527
528 SDL_HIDAPI_discovery.m_bInitialized = false;
529}
530
531// Platform HIDAPI Implementation
532
533#define HIDAPI_USING_SDL_RUNTIME
534#define HIDAPI_IGNORE_DEVICE(BUS, VID, PID, USAGE_PAGE, USAGE) \
535 SDL_HIDAPI_ShouldIgnoreDevice(BUS, VID, PID, USAGE_PAGE, USAGE)
536
537struct PLATFORM_hid_device_;
538typedef struct PLATFORM_hid_device_ PLATFORM_hid_device;
539
540#define api_version PLATFORM_api_version
541#define create_device_info_for_device PLATFORM_create_device_info_for_device
542#define free_hid_device PLATFORM_free_hid_device
543#define hid_close PLATFORM_hid_close
544#define hid_device PLATFORM_hid_device
545#define hid_device_ PLATFORM_hid_device_
546#define hid_enumerate PLATFORM_hid_enumerate
547#define hid_error PLATFORM_hid_error
548#define hid_exit PLATFORM_hid_exit
549#define hid_free_enumeration PLATFORM_hid_free_enumeration
550#define hid_get_device_info PLATFORM_hid_get_device_info
551#define hid_get_feature_report PLATFORM_hid_get_feature_report
552#define hid_get_indexed_string PLATFORM_hid_get_indexed_string
553#define hid_get_input_report PLATFORM_hid_get_input_report
554#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string
555#define hid_get_product_string PLATFORM_hid_get_product_string
556#define hid_get_report_descriptor PLATFORM_hid_get_report_descriptor
557#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string
558#define hid_init PLATFORM_hid_init
559#define hid_open_path PLATFORM_hid_open_path
560#define hid_open PLATFORM_hid_open
561#define hid_read PLATFORM_hid_read
562#define hid_read_timeout PLATFORM_hid_read_timeout
563#define hid_send_feature_report PLATFORM_hid_send_feature_report
564#define hid_set_nonblocking PLATFORM_hid_set_nonblocking
565#define hid_version PLATFORM_hid_version
566#define hid_version_str PLATFORM_hid_version_str
567#define hid_write PLATFORM_hid_write
568#define input_report PLATFORM_input_report
569#define make_path PLATFORM_make_path
570#define new_hid_device PLATFORM_new_hid_device
571#define read_thread PLATFORM_read_thread
572#define return_data PLATFORM_return_data
573
574#ifdef SDL_PLATFORM_LINUX
575#include "SDL_hidapi_linux.h"
576#elif defined(SDL_PLATFORM_NETBSD)
577#include "SDL_hidapi_netbsd.h"
578#elif defined(SDL_PLATFORM_MACOS)
579#include "SDL_hidapi_mac.h"
580#elif defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
581#include "SDL_hidapi_windows.h"
582#elif defined(SDL_PLATFORM_ANDROID)
583#include "SDL_hidapi_android.h"
584#elif defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS)
585#include "SDL_hidapi_ios.h"
586#endif
587
588#undef api_version
589#undef create_device_info_for_device
590#undef free_hid_device
591#undef hid_close
592#undef hid_device
593#undef hid_device_
594#undef hid_enumerate
595#undef hid_error
596#undef hid_exit
597#undef hid_free_enumeration
598#undef hid_get_device_info
599#undef hid_get_feature_report
600#undef hid_get_indexed_string
601#undef hid_get_input_report
602#undef hid_get_manufacturer_string
603#undef hid_get_product_string
604#undef hid_get_report_descriptor
605#undef hid_get_serial_number_string
606#undef hid_init
607#undef hid_open
608#undef hid_open_path
609#undef hid_read
610#undef hid_read_timeout
611#undef hid_send_feature_report
612#undef hid_set_nonblocking
613#undef hid_version
614#undef hid_version_str
615#undef hid_write
616#undef input_report
617#undef make_path
618#undef new_hid_device
619#undef read_thread
620#undef return_data
621
622#ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX
623#define HAVE_DRIVER_BACKEND 1
624#endif
625
626#ifdef HAVE_DRIVER_BACKEND
627
628// DRIVER HIDAPI Implementation
629
630struct DRIVER_hid_device_;
631typedef struct DRIVER_hid_device_ DRIVER_hid_device;
632
633#define hid_close DRIVER_hid_close
634#define hid_device DRIVER_hid_device
635#define hid_device_ DRIVER_hid_device_
636#define hid_enumerate DRIVER_hid_enumerate
637#define hid_error DRIVER_hid_error
638#define hid_exit DRIVER_hid_exit
639#define hid_free_enumeration DRIVER_hid_free_enumeration
640#define hid_get_device_info DRIVER_hid_get_device_info
641#define hid_get_feature_report DRIVER_hid_get_feature_report
642#define hid_get_indexed_string DRIVER_hid_get_indexed_string
643#define hid_get_input_report DRIVER_hid_get_input_report
644#define hid_get_manufacturer_string DRIVER_hid_get_manufacturer_string
645#define hid_get_product_string DRIVER_hid_get_product_string
646#define hid_get_report_descriptor DRIVER_hid_get_report_descriptor
647#define hid_get_serial_number_string DRIVER_hid_get_serial_number_string
648#define hid_init DRIVER_hid_init
649#define hid_open DRIVER_hid_open
650#define hid_open_path DRIVER_hid_open_path
651#define hid_read DRIVER_hid_read
652#define hid_read_timeout DRIVER_hid_read_timeout
653#define hid_send_feature_report DRIVER_hid_send_feature_report
654#define hid_set_nonblocking DRIVER_hid_set_nonblocking
655#define hid_write DRIVER_hid_write
656
657#ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX
658#include "SDL_hidapi_steamxbox.h"
659#else
660#error Need a driver hid.c for this platform!
661#endif
662
663#undef hid_close
664#undef hid_device
665#undef hid_device_
666#undef hid_enumerate
667#undef hid_error
668#undef hid_exit
669#undef hid_free_enumeration
670#undef hid_get_device_info
671#undef hid_get_feature_report
672#undef hid_get_indexed_string
673#undef hid_get_input_report
674#undef hid_get_manufacturer_string
675#undef hid_get_product_string
676#undef hid_get_report_descriptor
677#undef hid_get_serial_number_string
678#undef hid_init
679#undef hid_open
680#undef hid_open_path
681#undef hid_read
682#undef hid_read_timeout
683#undef hid_send_feature_report
684#undef hid_set_nonblocking
685#undef hid_write
686
687#endif // HAVE_DRIVER_BACKEND
688
689#ifdef HAVE_LIBUSB
690// libusb HIDAPI Implementation
691
692// Include this now, for our dynamically-loaded libusb context
693#include <libusb.h>
694
695static struct
696{
697 SDL_SharedObject *libhandle;
698
699 /* *INDENT-OFF* */ // clang-format off
700 int (LIBUSB_CALL *init)(libusb_context **ctx);
701 void (LIBUSB_CALL *exit)(libusb_context *ctx);
702 ssize_t (LIBUSB_CALL *get_device_list)(libusb_context *ctx, libusb_device ***list);
703 void (LIBUSB_CALL *free_device_list)(libusb_device **list, int unref_devices);
704 int (LIBUSB_CALL *get_device_descriptor)(libusb_device *dev, struct libusb_device_descriptor *desc);
705 int (LIBUSB_CALL *get_active_config_descriptor)(libusb_device *dev, struct libusb_config_descriptor **config);
706 int (LIBUSB_CALL *get_config_descriptor)(
707 libusb_device *dev,
708 uint8_t config_index,
709 struct libusb_config_descriptor **config
710 );
711 void (LIBUSB_CALL *free_config_descriptor)(struct libusb_config_descriptor *config);
712 uint8_t (LIBUSB_CALL *get_bus_number)(libusb_device *dev);
713 int (LIBUSB_CALL *get_port_numbers)(libusb_device *dev, uint8_t *port_numbers, int port_numbers_len);
714 uint8_t (LIBUSB_CALL *get_device_address)(libusb_device *dev);
715 int (LIBUSB_CALL *open)(libusb_device *dev, libusb_device_handle **dev_handle);
716 void (LIBUSB_CALL *close)(libusb_device_handle *dev_handle);
717 libusb_device *(LIBUSB_CALL *get_device)(libusb_device_handle *dev_handle);
718 int (LIBUSB_CALL *claim_interface)(libusb_device_handle *dev_handle, int interface_number);
719 int (LIBUSB_CALL *release_interface)(libusb_device_handle *dev_handle, int interface_number);
720 int (LIBUSB_CALL *kernel_driver_active)(libusb_device_handle *dev_handle, int interface_number);
721 int (LIBUSB_CALL *detach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number);
722 int (LIBUSB_CALL *attach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number);
723 int (LIBUSB_CALL *set_interface_alt_setting)(libusb_device_handle *dev, int interface_number, int alternate_setting);
724 struct libusb_transfer * (LIBUSB_CALL *alloc_transfer)(int iso_packets);
725 int (LIBUSB_CALL *submit_transfer)(struct libusb_transfer *transfer);
726 int (LIBUSB_CALL *cancel_transfer)(struct libusb_transfer *transfer);
727 void (LIBUSB_CALL *free_transfer)(struct libusb_transfer *transfer);
728 int (LIBUSB_CALL *control_transfer)(
729 libusb_device_handle *dev_handle,
730 uint8_t request_type,
731 uint8_t bRequest,
732 uint16_t wValue,
733 uint16_t wIndex,
734 unsigned char *data,
735 uint16_t wLength,
736 unsigned int timeout
737 );
738 int (LIBUSB_CALL *interrupt_transfer)(
739 libusb_device_handle *dev_handle,
740 unsigned char endpoint,
741 unsigned char *data,
742 int length,
743 int *actual_length,
744 unsigned int timeout
745 );
746 int (LIBUSB_CALL *handle_events)(libusb_context *ctx);
747 int (LIBUSB_CALL *handle_events_completed)(libusb_context *ctx, int *completed);
748 const char * (LIBUSB_CALL *error_name)(int errcode);
749/* *INDENT-ON* */ // clang-format on
750
751} libusb_ctx;
752
753#define libusb_init libusb_ctx.init
754#define libusb_exit libusb_ctx.exit
755#define libusb_get_device_list libusb_ctx.get_device_list
756#define libusb_free_device_list libusb_ctx.free_device_list
757#define libusb_get_device_descriptor libusb_ctx.get_device_descriptor
758#define libusb_get_active_config_descriptor libusb_ctx.get_active_config_descriptor
759#define libusb_get_config_descriptor libusb_ctx.get_config_descriptor
760#define libusb_free_config_descriptor libusb_ctx.free_config_descriptor
761#define libusb_get_bus_number libusb_ctx.get_bus_number
762#define libusb_get_port_numbers libusb_ctx.get_port_numbers
763#define libusb_get_device_address libusb_ctx.get_device_address
764#define libusb_open libusb_ctx.open
765#define libusb_close libusb_ctx.close
766#define libusb_get_device libusb_ctx.get_device
767#define libusb_claim_interface libusb_ctx.claim_interface
768#define libusb_release_interface libusb_ctx.release_interface
769#define libusb_kernel_driver_active libusb_ctx.kernel_driver_active
770#define libusb_detach_kernel_driver libusb_ctx.detach_kernel_driver
771#define libusb_attach_kernel_driver libusb_ctx.attach_kernel_driver
772#define libusb_set_interface_alt_setting libusb_ctx.set_interface_alt_setting
773#define libusb_alloc_transfer libusb_ctx.alloc_transfer
774#define libusb_submit_transfer libusb_ctx.submit_transfer
775#define libusb_cancel_transfer libusb_ctx.cancel_transfer
776#define libusb_free_transfer libusb_ctx.free_transfer
777#define libusb_control_transfer libusb_ctx.control_transfer
778#define libusb_interrupt_transfer libusb_ctx.interrupt_transfer
779#define libusb_handle_events libusb_ctx.handle_events
780#define libusb_handle_events_completed libusb_ctx.handle_events_completed
781#define libusb_error_name libusb_ctx.error_name
782
783struct LIBUSB_hid_device_;
784typedef struct LIBUSB_hid_device_ LIBUSB_hid_device;
785
786#define free_hid_device LIBUSB_free_hid_device
787#define hid_close LIBUSB_hid_close
788#define hid_device LIBUSB_hid_device
789#define hid_device_ LIBUSB_hid_device_
790#define hid_enumerate LIBUSB_hid_enumerate
791#define hid_error LIBUSB_hid_error
792#define hid_exit LIBUSB_hid_exit
793#define hid_free_enumeration LIBUSB_hid_free_enumeration
794#define hid_get_device_info LIBUSB_hid_get_device_info
795#define hid_get_feature_report LIBUSB_hid_get_feature_report
796#define hid_get_indexed_string LIBUSB_hid_get_indexed_string
797#define hid_get_input_report LIBUSB_hid_get_input_report
798#define hid_get_manufacturer_string LIBUSB_hid_get_manufacturer_string
799#define hid_get_product_string LIBUSB_hid_get_product_string
800#define hid_get_report_descriptor LIBUSB_hid_get_report_descriptor
801#define hid_get_serial_number_string LIBUSB_hid_get_serial_number_string
802#define hid_init LIBUSB_hid_init
803#define hid_open LIBUSB_hid_open
804#define hid_open_path LIBUSB_hid_open_path
805#define hid_read LIBUSB_hid_read
806#define hid_read_timeout LIBUSB_hid_read_timeout
807#define hid_send_feature_report LIBUSB_hid_send_feature_report
808#define hid_set_nonblocking LIBUSB_hid_set_nonblocking
809#define hid_write LIBUSB_hid_write
810#define input_report LIBUSB_input_report
811#define make_path LIBUSB_make_path
812#define new_hid_device LIBUSB_new_hid_device
813#define read_thread LIBUSB_read_thread
814#define return_data LIBUSB_return_data
815
816#include "SDL_hidapi_libusb.h"
817
818#undef libusb_init
819#undef libusb_exit
820#undef libusb_get_device_list
821#undef libusb_free_device_list
822#undef libusb_get_device_descriptor
823#undef libusb_get_active_config_descriptor
824#undef libusb_get_config_descriptor
825#undef libusb_free_config_descriptor
826#undef libusb_get_bus_number
827#undef libusb_get_port_numbers
828#undef libusb_get_device_address
829#undef libusb_open
830#undef libusb_close
831#undef libusb_get_device
832#undef libusb_claim_interface
833#undef libusb_release_interface
834#undef libusb_kernel_driver_active
835#undef libusb_detach_kernel_driver
836#undef libusb_attach_kernel_driver
837#undef libusb_set_interface_alt_setting
838#undef libusb_alloc_transfer
839#undef libusb_submit_transfer
840#undef libusb_cancel_transfer
841#undef libusb_free_transfer
842#undef libusb_control_transfer
843#undef libusb_interrupt_transfer
844#undef libusb_handle_events
845#undef libusb_handle_events_completed
846#undef libusb_error_name
847
848#undef free_hid_device
849#undef hid_close
850#undef hid_device
851#undef hid_device_
852#undef hid_enumerate
853#undef hid_error
854#undef hid_exit
855#undef hid_free_enumeration
856#undef hid_get_device_info
857#undef hid_get_feature_report
858#undef hid_get_indexed_string
859#undef hid_get_input_report
860#undef hid_get_manufacturer_string
861#undef hid_get_product_string
862#undef hid_get_report_descriptor
863#undef hid_get_serial_number_string
864#undef hid_init
865#undef hid_open
866#undef hid_open_path
867#undef hid_read
868#undef hid_read_timeout
869#undef hid_send_feature_report
870#undef hid_set_nonblocking
871#undef hid_write
872#undef input_report
873#undef make_path
874#undef new_hid_device
875#undef read_thread
876#undef return_data
877
878/* If the platform has any backend other than libusb, try to avoid using
879 * libusb as the main backend for devices, since it detaches drivers and
880 * therefore makes devices inaccessible to the rest of the OS.
881 *
882 * We do this by whitelisting devices we know to be accessible _exclusively_
883 * via libusb; these are typically devices that look like HIDs but have a
884 * quirk that requires direct access to the hardware.
885 */
886static const struct {
887 Uint16 vendor;
888 Uint16 product;
889} SDL_libusb_whitelist[] = {
890 { 0x057e, 0x0337 } // Nintendo WUP-028, Wii U/Switch GameCube Adapter
891};
892
893static bool IsInWhitelist(Uint16 vendor, Uint16 product)
894{
895 int i;
896 for (i = 0; i < SDL_arraysize(SDL_libusb_whitelist); i += 1) {
897 if (vendor == SDL_libusb_whitelist[i].vendor &&
898 product == SDL_libusb_whitelist[i].product) {
899 return true;
900 }
901 }
902 return false;
903}
904
905#endif // HAVE_LIBUSB
906
907#endif // !SDL_HIDAPI_DISABLED
908
909#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND)
910// We have another way to get HID devices, so use the whitelist to get devices where libusb is preferred
911#define SDL_HINT_HIDAPI_LIBUSB_WHITELIST_DEFAULT true
912#else
913// libusb is the only way to get HID devices, so don't use the whitelist, get them all
914#define SDL_HINT_HIDAPI_LIBUSB_WHITELIST_DEFAULT false
915#endif // HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND
916
917static bool use_libusb_whitelist = SDL_HINT_HIDAPI_LIBUSB_WHITELIST_DEFAULT;
918
919// Shared HIDAPI Implementation
920
921struct hidapi_backend
922{
923 int (*hid_write)(void *device, const unsigned char *data, size_t length);
924 int (*hid_read_timeout)(void *device, unsigned char *data, size_t length, int milliseconds);
925 int (*hid_read)(void *device, unsigned char *data, size_t length);
926 int (*hid_set_nonblocking)(void *device, int nonblock);
927 int (*hid_send_feature_report)(void *device, const unsigned char *data, size_t length);
928 int (*hid_get_feature_report)(void *device, unsigned char *data, size_t length);
929 int (*hid_get_input_report)(void *device, unsigned char *data, size_t length);
930 void (*hid_close)(void *device);
931 int (*hid_get_manufacturer_string)(void *device, wchar_t *string, size_t maxlen);
932 int (*hid_get_product_string)(void *device, wchar_t *string, size_t maxlen);
933 int (*hid_get_serial_number_string)(void *device, wchar_t *string, size_t maxlen);
934 int (*hid_get_indexed_string)(void *device, int string_index, wchar_t *string, size_t maxlen);
935 struct hid_device_info *(*hid_get_device_info)(void *device);
936 int (*hid_get_report_descriptor)(void *device, unsigned char *buf, size_t buf_size);
937 const wchar_t *(*hid_error)(void *device);
938};
939
940#ifdef HAVE_PLATFORM_BACKEND
941static const struct hidapi_backend PLATFORM_Backend = {
942 (void *)PLATFORM_hid_write,
943 (void *)PLATFORM_hid_read_timeout,
944 (void *)PLATFORM_hid_read,
945 (void *)PLATFORM_hid_set_nonblocking,
946 (void *)PLATFORM_hid_send_feature_report,
947 (void *)PLATFORM_hid_get_feature_report,
948 (void *)PLATFORM_hid_get_input_report,
949 (void *)PLATFORM_hid_close,
950 (void *)PLATFORM_hid_get_manufacturer_string,
951 (void *)PLATFORM_hid_get_product_string,
952 (void *)PLATFORM_hid_get_serial_number_string,
953 (void *)PLATFORM_hid_get_indexed_string,
954 (void *)PLATFORM_hid_get_device_info,
955 (void *)PLATFORM_hid_get_report_descriptor,
956 (void *)PLATFORM_hid_error
957};
958#endif // HAVE_PLATFORM_BACKEND
959
960#ifdef HAVE_DRIVER_BACKEND
961static const struct hidapi_backend DRIVER_Backend = {
962 (void *)DRIVER_hid_write,
963 (void *)DRIVER_hid_read_timeout,
964 (void *)DRIVER_hid_read,
965 (void *)DRIVER_hid_set_nonblocking,
966 (void *)DRIVER_hid_send_feature_report,
967 (void *)DRIVER_hid_get_feature_report,
968 (void *)DRIVER_hid_get_input_report,
969 (void *)DRIVER_hid_close,
970 (void *)DRIVER_hid_get_manufacturer_string,
971 (void *)DRIVER_hid_get_product_string,
972 (void *)DRIVER_hid_get_serial_number_string,
973 (void *)DRIVER_hid_get_indexed_string,
974 (void *)DRIVER_hid_get_device_info,
975 (void *)DRIVER_hid_get_report_descriptor,
976 (void *)DRIVER_hid_error
977};
978#endif // HAVE_DRIVER_BACKEND
979
980#ifdef HAVE_LIBUSB
981static const struct hidapi_backend LIBUSB_Backend = {
982 (void *)LIBUSB_hid_write,
983 (void *)LIBUSB_hid_read_timeout,
984 (void *)LIBUSB_hid_read,
985 (void *)LIBUSB_hid_set_nonblocking,
986 (void *)LIBUSB_hid_send_feature_report,
987 (void *)LIBUSB_hid_get_feature_report,
988 (void *)LIBUSB_hid_get_input_report,
989 (void *)LIBUSB_hid_close,
990 (void *)LIBUSB_hid_get_manufacturer_string,
991 (void *)LIBUSB_hid_get_product_string,
992 (void *)LIBUSB_hid_get_serial_number_string,
993 (void *)LIBUSB_hid_get_indexed_string,
994 (void *)LIBUSB_hid_get_device_info,
995 (void *)LIBUSB_hid_get_report_descriptor,
996 (void *)LIBUSB_hid_error
997};
998#endif // HAVE_LIBUSB
999
1000struct SDL_hid_device
1001{
1002 void *device;
1003 const struct hidapi_backend *backend;
1004 SDL_hid_device_info info;
1005};
1006
1007#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
1008
1009static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend)
1010{
1011 SDL_hid_device *wrapper = (SDL_hid_device *)SDL_malloc(sizeof(*wrapper));
1012 SDL_SetObjectValid(wrapper, SDL_OBJECT_TYPE_HIDAPI_DEVICE, true);
1013 wrapper->device = device;
1014 wrapper->backend = backend;
1015 SDL_zero(wrapper->info);
1016 return wrapper;
1017}
1018
1019#endif // HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB
1020
1021static void DeleteHIDDeviceWrapper(SDL_hid_device *wrapper)
1022{
1023 SDL_SetObjectValid(wrapper, SDL_OBJECT_TYPE_HIDAPI_DEVICE, false);
1024 SDL_free(wrapper->info.path);
1025 SDL_free(wrapper->info.serial_number);
1026 SDL_free(wrapper->info.manufacturer_string);
1027 SDL_free(wrapper->info.product_string);
1028 SDL_free(wrapper);
1029}
1030
1031#define CHECK_DEVICE_MAGIC(device, result) \
1032 if (!SDL_ObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_DEVICE)) { \
1033 SDL_SetError("Invalid device"); \
1034 return result; \
1035 }
1036
1037#define COPY_IF_EXISTS(var) \
1038 if (pSrc->var != NULL) { \
1039 pDst->var = SDL_strdup(pSrc->var); \
1040 } else { \
1041 pDst->var = NULL; \
1042 }
1043#define WCOPY_IF_EXISTS(var) \
1044 if (pSrc->var != NULL) { \
1045 pDst->var = SDL_wcsdup(pSrc->var); \
1046 } else { \
1047 pDst->var = NULL; \
1048 }
1049
1050static void CopyHIDDeviceInfo(struct hid_device_info *pSrc, struct SDL_hid_device_info *pDst)
1051{
1052 COPY_IF_EXISTS(path)
1053 pDst->vendor_id = pSrc->vendor_id;
1054 pDst->product_id = pSrc->product_id;
1055 WCOPY_IF_EXISTS(serial_number)
1056 pDst->release_number = pSrc->release_number;
1057 WCOPY_IF_EXISTS(manufacturer_string)
1058 WCOPY_IF_EXISTS(product_string)
1059 pDst->usage_page = pSrc->usage_page;
1060 pDst->usage = pSrc->usage;
1061 pDst->interface_number = pSrc->interface_number;
1062 pDst->interface_class = pSrc->interface_class;
1063 pDst->interface_subclass = pSrc->interface_subclass;
1064 pDst->interface_protocol = pSrc->interface_protocol;
1065 pDst->bus_type = (SDL_hid_bus_type)pSrc->bus_type;
1066 pDst->next = NULL;
1067}
1068
1069#undef COPY_IF_EXISTS
1070#undef WCOPY_IF_EXISTS
1071
1072static int SDL_hidapi_refcount = 0;
1073static bool SDL_hidapi_only_controllers;
1074static char *SDL_hidapi_ignored_devices = NULL;
1075
1076static void SDLCALL OnlyControllersChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
1077{
1078 SDL_hidapi_only_controllers = SDL_GetStringBoolean(hint, true);
1079}
1080
1081static void SDLCALL IgnoredDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
1082{
1083 if (SDL_hidapi_ignored_devices) {
1084 SDL_free(SDL_hidapi_ignored_devices);
1085 }
1086 if (hint && *hint) {
1087 SDL_hidapi_ignored_devices = SDL_strdup(hint);
1088 } else {
1089 SDL_hidapi_ignored_devices = NULL;
1090 }
1091}
1092
1093bool SDL_HIDAPI_ShouldIgnoreDevice(int bus, Uint16 vendor_id, Uint16 product_id, Uint16 usage_page, Uint16 usage)
1094{
1095 // See if there are any devices we should skip in enumeration
1096 if (SDL_hidapi_only_controllers && usage_page) {
1097 if (vendor_id == USB_VENDOR_VALVE) {
1098 // Ignore the mouse/keyboard interface on Steam Controllers
1099 if (
1100#ifdef SDL_PLATFORM_WIN32
1101 // Check the usage page and usage on both USB and Bluetooth
1102#else
1103 // Only check the usage page and usage on USB
1104 bus == HID_API_BUS_USB &&
1105#endif
1106 usage_page == USB_USAGEPAGE_GENERIC_DESKTOP &&
1107 (usage == USB_USAGE_GENERIC_KEYBOARD || usage == USB_USAGE_GENERIC_MOUSE)) {
1108 return true;
1109 }
1110 } else if (usage_page == USB_USAGEPAGE_GENERIC_DESKTOP &&
1111 (usage == USB_USAGE_GENERIC_JOYSTICK || usage == USB_USAGE_GENERIC_GAMEPAD || usage == USB_USAGE_GENERIC_MULTIAXISCONTROLLER)) {
1112 // This is a controller
1113 } else {
1114 return true;
1115 }
1116 }
1117 if (SDL_hidapi_ignored_devices) {
1118 char vendor_match[16], product_match[16];
1119 SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", vendor_id);
1120 SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", vendor_id, product_id);
1121 if (SDL_strcasestr(SDL_hidapi_ignored_devices, vendor_match) ||
1122 SDL_strcasestr(SDL_hidapi_ignored_devices, product_match)) {
1123 return true;
1124 }
1125 }
1126 return false;
1127}
1128
1129int SDL_hid_init(void)
1130{
1131 int attempts = 0, success = 0;
1132
1133 if (SDL_hidapi_refcount > 0) {
1134 ++SDL_hidapi_refcount;
1135 return 0;
1136 }
1137
1138 SDL_AddHintCallback(SDL_HINT_HIDAPI_ENUMERATE_ONLY_CONTROLLERS, OnlyControllersChanged, NULL);
1139 SDL_AddHintCallback(SDL_HINT_HIDAPI_IGNORE_DEVICES, IgnoredDevicesChanged, NULL);
1140
1141#ifdef SDL_USE_LIBUDEV
1142 if (!SDL_GetHintBoolean(SDL_HINT_HIDAPI_UDEV, true)) {
1143 SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
1144 "udev disabled by SDL_HINT_HIDAPI_UDEV");
1145 linux_enumeration_method = ENUMERATION_FALLBACK;
1146 } else if (SDL_GetSandbox() != SDL_SANDBOX_NONE) {
1147 SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
1148 "Container detected, disabling HIDAPI udev integration");
1149 linux_enumeration_method = ENUMERATION_FALLBACK;
1150 } else {
1151 SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
1152 "Using udev for HIDAPI joystick device discovery");
1153 linux_enumeration_method = ENUMERATION_LIBUDEV;
1154 }
1155#endif
1156
1157 use_libusb_whitelist = SDL_GetHintBoolean(SDL_HINT_HIDAPI_LIBUSB_WHITELIST,
1158 SDL_HINT_HIDAPI_LIBUSB_WHITELIST_DEFAULT);
1159#ifdef HAVE_LIBUSB
1160 if (!SDL_GetHintBoolean(SDL_HINT_HIDAPI_LIBUSB, true)) {
1161 SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
1162 "libusb disabled with SDL_HINT_HIDAPI_LIBUSB");
1163 libusb_ctx.libhandle = NULL;
1164 } else {
1165 ++attempts;
1166#ifdef SDL_LIBUSB_DYNAMIC
1167 libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC);
1168#else
1169 libusb_ctx.libhandle = (void *)1;
1170#endif
1171 if (libusb_ctx.libhandle != NULL) {
1172 bool loaded = true;
1173#ifdef SDL_LIBUSB_DYNAMIC
1174#define LOAD_LIBUSB_SYMBOL(type, func) \
1175 if (!(libusb_ctx.func = (type)SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) { \
1176 loaded = false; \
1177 }
1178#else
1179#define LOAD_LIBUSB_SYMBOL(type, func) \
1180 libusb_ctx.func = libusb_##func;
1181#endif
1182 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_context **), init)
1183 LOAD_LIBUSB_SYMBOL(void (LIBUSB_CALL *)(libusb_context *), exit)
1184 LOAD_LIBUSB_SYMBOL(ssize_t (LIBUSB_CALL *)(libusb_context *, libusb_device ***), get_device_list)
1185 LOAD_LIBUSB_SYMBOL(void (LIBUSB_CALL *)(libusb_device **, int), free_device_list)
1186 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device *, struct libusb_device_descriptor *), get_device_descriptor)
1187 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device *, struct libusb_config_descriptor **), get_active_config_descriptor)
1188 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device *, uint8_t, struct libusb_config_descriptor **), get_config_descriptor)
1189 LOAD_LIBUSB_SYMBOL(void (LIBUSB_CALL *)(struct libusb_config_descriptor *), free_config_descriptor)
1190 LOAD_LIBUSB_SYMBOL(uint8_t (LIBUSB_CALL *)(libusb_device *), get_bus_number)
1191 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device *dev, uint8_t *port_numbers, int port_numbers_len), get_port_numbers)
1192 LOAD_LIBUSB_SYMBOL(uint8_t (LIBUSB_CALL *)(libusb_device *), get_device_address)
1193 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device *, libusb_device_handle **), open)
1194 LOAD_LIBUSB_SYMBOL(void (LIBUSB_CALL *)(libusb_device_handle *), close)
1195 LOAD_LIBUSB_SYMBOL(libusb_device * (LIBUSB_CALL *)(libusb_device_handle *dev_handle), get_device)
1196 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, int), claim_interface)
1197 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, int), release_interface)
1198 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, int), kernel_driver_active)
1199 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, int), detach_kernel_driver)
1200 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, int), attach_kernel_driver)
1201 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, int, int), set_interface_alt_setting)
1202 LOAD_LIBUSB_SYMBOL(struct libusb_transfer * (LIBUSB_CALL *)(int), alloc_transfer)
1203 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(struct libusb_transfer *), submit_transfer)
1204 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(struct libusb_transfer *), cancel_transfer)
1205 LOAD_LIBUSB_SYMBOL(void (LIBUSB_CALL *)(struct libusb_transfer *), free_transfer)
1206 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, uint8_t, uint8_t, uint16_t, uint16_t, unsigned char *, uint16_t, unsigned int), control_transfer)
1207 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_device_handle *, unsigned char, unsigned char *, int, int *, unsigned int), interrupt_transfer)
1208 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_context *), handle_events)
1209 LOAD_LIBUSB_SYMBOL(int (LIBUSB_CALL *)(libusb_context *, int *), handle_events_completed)
1210 LOAD_LIBUSB_SYMBOL(const char * (LIBUSB_CALL *)(int), error_name)
1211#undef LOAD_LIBUSB_SYMBOL
1212
1213 if (!loaded) {
1214#ifdef SDL_LIBUSB_DYNAMIC
1215 SDL_UnloadObject(libusb_ctx.libhandle);
1216#endif
1217 libusb_ctx.libhandle = NULL;
1218 // SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function");
1219 } else if (LIBUSB_hid_init() < 0) {
1220#ifdef SDL_LIBUSB_DYNAMIC
1221 SDL_UnloadObject(libusb_ctx.libhandle);
1222#endif
1223 libusb_ctx.libhandle = NULL;
1224 } else {
1225 ++success;
1226 }
1227 }
1228 }
1229#endif // HAVE_LIBUSB
1230
1231#ifdef HAVE_PLATFORM_BACKEND
1232 ++attempts;
1233#ifdef SDL_PLATFORM_LINUX
1234 udev_ctx = SDL_UDEV_GetUdevSyms();
1235#endif // __LINUX __
1236 if (udev_ctx && PLATFORM_hid_init() == 0) {
1237 ++success;
1238 }
1239#endif // HAVE_PLATFORM_BACKEND
1240
1241 if (attempts > 0 && success == 0) {
1242 return -1;
1243 }
1244
1245#if defined(SDL_PLATFORM_MACOS) && !defined(SDL_HIDAPI_DISABLED)
1246 hid_darwin_set_open_exclusive(0);
1247#endif
1248
1249 ++SDL_hidapi_refcount;
1250 return 0;
1251}
1252
1253int SDL_hid_exit(void)
1254{
1255 int result = 0;
1256
1257 if (SDL_hidapi_refcount == 0) {
1258 return 0;
1259 }
1260 --SDL_hidapi_refcount;
1261 if (SDL_hidapi_refcount > 0) {
1262 return 0;
1263 }
1264 SDL_hidapi_refcount = 0;
1265
1266#ifndef SDL_HIDAPI_DISABLED
1267 HIDAPI_ShutdownDiscovery();
1268#endif
1269
1270#ifdef HAVE_PLATFORM_BACKEND
1271 if (udev_ctx) {
1272 result |= PLATFORM_hid_exit();
1273 }
1274#ifdef SDL_PLATFORM_LINUX
1275 SDL_UDEV_ReleaseUdevSyms();
1276#endif // __LINUX __
1277#endif // HAVE_PLATFORM_BACKEND
1278
1279#ifdef HAVE_LIBUSB
1280 if (libusb_ctx.libhandle) {
1281 result |= LIBUSB_hid_exit();
1282#ifdef SDL_LIBUSB_DYNAMIC
1283 SDL_UnloadObject(libusb_ctx.libhandle);
1284#endif
1285 libusb_ctx.libhandle = NULL;
1286 }
1287#endif // HAVE_LIBUSB
1288
1289 SDL_RemoveHintCallback(SDL_HINT_HIDAPI_ENUMERATE_ONLY_CONTROLLERS, OnlyControllersChanged, NULL);
1290 SDL_RemoveHintCallback(SDL_HINT_HIDAPI_IGNORE_DEVICES, IgnoredDevicesChanged, NULL);
1291
1292 if (SDL_hidapi_ignored_devices) {
1293 SDL_free(SDL_hidapi_ignored_devices);
1294 SDL_hidapi_ignored_devices = NULL;
1295 }
1296
1297 return result;
1298}
1299
1300Uint32 SDL_hid_device_change_count(void)
1301{
1302 Uint32 counter = 0;
1303
1304#ifndef SDL_HIDAPI_DISABLED
1305 if (SDL_hidapi_refcount == 0 && SDL_hid_init() < 0) {
1306 return 0;
1307 }
1308
1309 HIDAPI_UpdateDiscovery();
1310
1311 if (SDL_HIDAPI_discovery.m_unDeviceChangeCounter == 0) {
1312 // Counter wrapped!
1313 ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
1314 }
1315 counter = SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
1316
1317#endif // !SDL_HIDAPI_DISABLED
1318
1319 return counter;
1320}
1321
1322static void AddDeviceToEnumeration(const char *driver_name, struct hid_device_info *dev, struct SDL_hid_device_info **devs, struct SDL_hid_device_info **last)
1323{
1324 struct SDL_hid_device_info *new_dev;
1325
1326#ifdef DEBUG_HIDAPI
1327 SDL_Log("Adding %s device to enumeration: %ls %ls 0x%.4hx/0x%.4hx/%d",
1328 driver_name, dev->manufacturer_string, dev->product_string, dev->vendor_id, dev->product_id, dev->interface_number);
1329#else
1330 (void)driver_name;
1331#endif
1332
1333 new_dev = (struct SDL_hid_device_info *)SDL_malloc(sizeof(struct SDL_hid_device_info));
1334 if (new_dev == NULL) {
1335 // Don't bother returning an error, get as many devices as possible
1336 return;
1337 }
1338 CopyHIDDeviceInfo(dev, new_dev);
1339
1340 if ((*last) != NULL) {
1341 (*last)->next = new_dev;
1342 } else {
1343 *devs = new_dev;
1344 }
1345 *last = new_dev;
1346}
1347
1348#if defined(HAVE_LIBUSB) || defined(HAVE_PLATFORM_BACKEND)
1349static void RemoveDeviceFromEnumeration(const char *driver_name, struct hid_device_info *dev, struct hid_device_info **devs, void (*free_device_info)(struct hid_device_info *))
1350{
1351 struct hid_device_info *last = NULL, *curr, *next;
1352
1353 for (curr = *devs; curr; curr = next) {
1354 next = curr->next;
1355
1356 if (dev->vendor_id == curr->vendor_id &&
1357 dev->product_id == curr->product_id &&
1358 (dev->interface_number < 0 || curr->interface_number < 0 || dev->interface_number == curr->interface_number)) {
1359#ifdef DEBUG_HIDAPI
1360 SDL_Log("Skipping %s device: %ls %ls 0x%.4hx/0x%.4hx/%d",
1361 driver_name, curr->manufacturer_string, curr->product_string, curr->vendor_id, curr->product_id, curr->interface_number);
1362#else
1363 (void)driver_name;
1364#endif
1365 if (last) {
1366 last->next = next;
1367 } else {
1368 *devs = next;
1369 }
1370
1371 curr->next = NULL;
1372 free_device_info(curr);
1373 continue;
1374 }
1375 last = curr;
1376 }
1377}
1378#endif // HAVE_LIBUSB || HAVE_PLATFORM_BACKEND
1379
1380#ifdef HAVE_LIBUSB
1381static void RemoveNonWhitelistedDevicesFromEnumeration(struct hid_device_info **devs, void (*free_device_info)(struct hid_device_info *))
1382{
1383 struct hid_device_info *last = NULL, *curr, *next;
1384
1385 for (curr = *devs; curr; curr = next) {
1386 next = curr->next;
1387
1388 if (!IsInWhitelist(curr->vendor_id, curr->product_id)) {
1389#ifdef DEBUG_HIDAPI
1390 SDL_Log("Device was not in libusb whitelist, skipping: %ls %ls 0x%.4hx/0x%.4hx/%d",
1391 curr->manufacturer_string, curr->product_string, curr->vendor_id, curr->product_id, curr->interface_number);
1392#endif
1393 if (last) {
1394 last->next = next;
1395 } else {
1396 *devs = next;
1397 }
1398
1399 curr->next = NULL;
1400 free_device_info(curr);
1401 continue;
1402 }
1403 last = curr;
1404 }
1405}
1406#endif // HAVE_LIBUSB
1407
1408struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id)
1409{
1410 struct hid_device_info *driver_devs = NULL;
1411 struct hid_device_info *usb_devs = NULL;
1412 struct hid_device_info *raw_devs = NULL;
1413 struct hid_device_info *dev;
1414 struct SDL_hid_device_info *devs = NULL, *last = NULL;
1415
1416 if (SDL_hidapi_refcount == 0 && SDL_hid_init() < 0) {
1417 return NULL;
1418 }
1419
1420 // Collect the available devices
1421#ifdef HAVE_DRIVER_BACKEND
1422 driver_devs = DRIVER_hid_enumerate(vendor_id, product_id);
1423#endif
1424
1425#ifdef HAVE_LIBUSB
1426 if (libusb_ctx.libhandle) {
1427 usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
1428
1429 if (use_libusb_whitelist) {
1430 RemoveNonWhitelistedDevicesFromEnumeration(&usb_devs, LIBUSB_hid_free_enumeration);
1431 }
1432 }
1433#endif // HAVE_LIBUSB
1434
1435#ifdef HAVE_PLATFORM_BACKEND
1436 if (udev_ctx) {
1437 raw_devs = PLATFORM_hid_enumerate(vendor_id, product_id);
1438 }
1439#endif
1440
1441 // Highest priority are custom driver devices
1442 for (dev = driver_devs; dev; dev = dev->next) {
1443 AddDeviceToEnumeration("driver", dev, &devs, &last);
1444#ifdef HAVE_LIBUSB
1445 RemoveDeviceFromEnumeration("libusb", dev, &usb_devs, LIBUSB_hid_free_enumeration);
1446#endif
1447#ifdef HAVE_PLATFORM_BACKEND
1448 RemoveDeviceFromEnumeration("raw", dev, &raw_devs, PLATFORM_hid_free_enumeration);
1449#endif
1450 }
1451
1452 // If whitelist is in effect, libusb has priority, otherwise raw devices do
1453 if (use_libusb_whitelist) {
1454 for (dev = usb_devs; dev; dev = dev->next) {
1455 AddDeviceToEnumeration("libusb", dev, &devs, &last);
1456#ifdef HAVE_PLATFORM_BACKEND
1457 RemoveDeviceFromEnumeration("raw", dev, &raw_devs, PLATFORM_hid_free_enumeration);
1458#endif
1459 }
1460 for (dev = raw_devs; dev; dev = dev->next) {
1461 AddDeviceToEnumeration("platform", dev, &devs, &last);
1462 }
1463 } else {
1464 for (dev = raw_devs; dev; dev = dev->next) {
1465 AddDeviceToEnumeration("raw", dev, &devs, &last);
1466#ifdef HAVE_LIBUSB
1467 RemoveDeviceFromEnumeration("libusb", dev, &usb_devs, LIBUSB_hid_free_enumeration);
1468#endif
1469 }
1470 for (dev = usb_devs; dev; dev = dev->next) {
1471 AddDeviceToEnumeration("libusb", dev, &devs, &last);
1472 }
1473 }
1474
1475#ifdef HAVE_DRIVER_BACKEND
1476 DRIVER_hid_free_enumeration(driver_devs);
1477#endif
1478#ifdef HAVE_LIBUSB
1479 LIBUSB_hid_free_enumeration(usb_devs);
1480#endif
1481#ifdef HAVE_PLATFORM_BACKEND
1482 PLATFORM_hid_free_enumeration(raw_devs);
1483#endif
1484
1485 return devs;
1486}
1487
1488void SDL_hid_free_enumeration(struct SDL_hid_device_info *devs)
1489{
1490 while (devs) {
1491 struct SDL_hid_device_info *next = devs->next;
1492 SDL_free(devs->path);
1493 SDL_free(devs->serial_number);
1494 SDL_free(devs->manufacturer_string);
1495 SDL_free(devs->product_string);
1496 SDL_free(devs);
1497 devs = next;
1498 }
1499}
1500
1501SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
1502{
1503#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
1504 void *pDevice = NULL;
1505
1506 if (SDL_hidapi_refcount == 0 && SDL_hid_init() < 0) {
1507 return NULL;
1508 }
1509
1510#ifdef HAVE_PLATFORM_BACKEND
1511 if (udev_ctx) {
1512 pDevice = PLATFORM_hid_open(vendor_id, product_id, serial_number);
1513 if (pDevice != NULL) {
1514 return CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
1515 }
1516 }
1517#endif // HAVE_PLATFORM_BACKEND
1518
1519#ifdef HAVE_DRIVER_BACKEND
1520 pDevice = DRIVER_hid_open(vendor_id, product_id, serial_number);
1521 if (pDevice != NULL) {
1522 return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);
1523 }
1524#endif // HAVE_DRIVER_BACKEND
1525
1526#ifdef HAVE_LIBUSB
1527 if (libusb_ctx.libhandle != NULL) {
1528 pDevice = LIBUSB_hid_open(vendor_id, product_id, serial_number);
1529 if (pDevice != NULL) {
1530 return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
1531 }
1532 }
1533#endif // HAVE_LIBUSB
1534
1535#endif // HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB
1536
1537 return NULL;
1538}
1539
1540SDL_hid_device *SDL_hid_open_path(const char *path)
1541{
1542#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
1543 void *pDevice = NULL;
1544
1545 if (SDL_hidapi_refcount == 0 && SDL_hid_init() < 0) {
1546 return NULL;
1547 }
1548
1549#ifdef HAVE_PLATFORM_BACKEND
1550 if (udev_ctx) {
1551 pDevice = PLATFORM_hid_open_path(path);
1552 if (pDevice != NULL) {
1553 return CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
1554 }
1555 }
1556#endif // HAVE_PLATFORM_BACKEND
1557
1558#ifdef HAVE_DRIVER_BACKEND
1559 pDevice = DRIVER_hid_open_path(path);
1560 if (pDevice != NULL) {
1561 return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);
1562 }
1563#endif // HAVE_DRIVER_BACKEND
1564
1565#ifdef HAVE_LIBUSB
1566 if (libusb_ctx.libhandle != NULL) {
1567 pDevice = LIBUSB_hid_open_path(path);
1568 if (pDevice != NULL) {
1569 return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
1570 }
1571 }
1572#endif // HAVE_LIBUSB
1573
1574#endif // HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB
1575
1576 return NULL;
1577}
1578
1579int SDL_hid_write(SDL_hid_device *device, const unsigned char *data, size_t length)
1580{
1581 CHECK_DEVICE_MAGIC(device, -1);
1582
1583 return device->backend->hid_write(device->device, data, length);
1584}
1585
1586int SDL_hid_read_timeout(SDL_hid_device *device, unsigned char *data, size_t length, int milliseconds)
1587{
1588 CHECK_DEVICE_MAGIC(device, -1);
1589
1590 return device->backend->hid_read_timeout(device->device, data, length, milliseconds);
1591}
1592
1593int SDL_hid_read(SDL_hid_device *device, unsigned char *data, size_t length)
1594{
1595 CHECK_DEVICE_MAGIC(device, -1);
1596
1597 return device->backend->hid_read(device->device, data, length);
1598}
1599
1600int SDL_hid_set_nonblocking(SDL_hid_device *device, int nonblock)
1601{
1602 CHECK_DEVICE_MAGIC(device, -1);
1603
1604 return device->backend->hid_set_nonblocking(device->device, nonblock);
1605}
1606
1607int SDL_hid_send_feature_report(SDL_hid_device *device, const unsigned char *data, size_t length)
1608{
1609 CHECK_DEVICE_MAGIC(device, -1);
1610
1611 return device->backend->hid_send_feature_report(device->device, data, length);
1612}
1613
1614int SDL_hid_get_feature_report(SDL_hid_device *device, unsigned char *data, size_t length)
1615{
1616 CHECK_DEVICE_MAGIC(device, -1);
1617
1618 return device->backend->hid_get_feature_report(device->device, data, length);
1619}
1620
1621int SDL_hid_get_input_report(SDL_hid_device *device, unsigned char *data, size_t length)
1622{
1623 CHECK_DEVICE_MAGIC(device, -1);
1624
1625 return device->backend->hid_get_input_report(device->device, data, length);
1626}
1627
1628int SDL_hid_close(SDL_hid_device *device)
1629{
1630 CHECK_DEVICE_MAGIC(device, -1);
1631
1632 device->backend->hid_close(device->device);
1633 DeleteHIDDeviceWrapper(device);
1634 return 0;
1635}
1636
1637int SDL_hid_get_manufacturer_string(SDL_hid_device *device, wchar_t *string, size_t maxlen)
1638{
1639 CHECK_DEVICE_MAGIC(device, -1);
1640
1641 return device->backend->hid_get_manufacturer_string(device->device, string, maxlen);
1642}
1643
1644int SDL_hid_get_product_string(SDL_hid_device *device, wchar_t *string, size_t maxlen)
1645{
1646 CHECK_DEVICE_MAGIC(device, -1);
1647
1648 return device->backend->hid_get_product_string(device->device, string, maxlen);
1649}
1650
1651int SDL_hid_get_serial_number_string(SDL_hid_device *device, wchar_t *string, size_t maxlen)
1652{
1653 CHECK_DEVICE_MAGIC(device, -1);
1654
1655 return device->backend->hid_get_serial_number_string(device->device, string, maxlen);
1656}
1657
1658int SDL_hid_get_indexed_string(SDL_hid_device *device, int string_index, wchar_t *string, size_t maxlen)
1659{
1660 CHECK_DEVICE_MAGIC(device, -1);
1661
1662 return device->backend->hid_get_indexed_string(device->device, string_index, string, maxlen);
1663}
1664
1665SDL_hid_device_info *SDL_hid_get_device_info(SDL_hid_device *device)
1666{
1667 struct hid_device_info *info;
1668
1669 CHECK_DEVICE_MAGIC(device, NULL);
1670
1671 info = device->backend->hid_get_device_info(device->device);
1672 if (info) {
1673 CopyHIDDeviceInfo(info, &device->info);
1674 return &device->info;
1675 } else {
1676 return NULL;
1677 }
1678}
1679
1680int SDL_hid_get_report_descriptor(SDL_hid_device *device, unsigned char *buf, size_t buf_size)
1681{
1682 CHECK_DEVICE_MAGIC(device, -1);
1683
1684 return device->backend->hid_get_report_descriptor(device->device, buf, buf_size);
1685}
1686
1687void SDL_hid_ble_scan(bool active)
1688{
1689#if !defined(SDL_HIDAPI_DISABLED) && (defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS))
1690 extern void hid_ble_scan(int bStart);
1691 hid_ble_scan(active);
1692#endif
1693}
1694
1695#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS
1696// This is needed to enable input for Nyko and EVORETRO GameCube adaptors
1697void SDL_EnableGameCubeAdaptors(void)
1698{
1699#ifdef HAVE_LIBUSB
1700 libusb_context *context = NULL;
1701 libusb_device **devs = NULL;
1702 libusb_device_handle *handle = NULL;
1703 struct libusb_device_descriptor desc;
1704 ssize_t i, num_devs;
1705 int kernel_detached = 0;
1706
1707 if (libusb_ctx.libhandle == NULL) {
1708 return;
1709 }
1710
1711 if (libusb_ctx.init(&context) == 0) {
1712 num_devs = libusb_ctx.get_device_list(context, &devs);
1713 for (i = 0; i < num_devs; ++i) {
1714 if (libusb_ctx.get_device_descriptor(devs[i], &desc) != 0) {
1715 continue;
1716 }
1717
1718 if (desc.idVendor != 0x057e || desc.idProduct != 0x0337) {
1719 continue;
1720 }
1721
1722 if (libusb_ctx.open(devs[i], &handle) != 0) {
1723 continue;
1724 }
1725
1726 if (libusb_ctx.kernel_driver_active(handle, 0)) {
1727 if (libusb_ctx.detach_kernel_driver(handle, 0) == 0) {
1728 kernel_detached = 1;
1729 }
1730 }
1731
1732 if (libusb_ctx.claim_interface(handle, 0) == 0) {
1733 libusb_ctx.control_transfer(handle, 0x21, 11, 0x0001, 0, NULL, 0, 1000);
1734 libusb_ctx.release_interface(handle, 0);
1735 }
1736
1737 if (kernel_detached) {
1738 libusb_ctx.attach_kernel_driver(handle, 0);
1739 }
1740
1741 libusb_ctx.close(handle);
1742 }
1743
1744 libusb_ctx.free_device_list(devs, 1);
1745
1746 libusb_ctx.exit(context);
1747 }
1748#endif // HAVE_LIBUSB
1749}
1750#endif // HAVE_ENABLE_GAMECUBE_ADAPTORS
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_android.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_android.h
new file mode 100644
index 0000000..2f3851f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_android.h
@@ -0,0 +1,26 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/* The implementation for Android is in a separate .cpp file */
23#undef HIDAPI_H__
24#include "hidapi/hidapi.h"
25#define HAVE_PLATFORM_BACKEND 1
26#define udev_ctx 1
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_c.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_c.h
new file mode 100644
index 0000000..6d94f77
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_c.h
@@ -0,0 +1,35 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23
24/* Return true if the HIDAPI should ignore a device during enumeration */
25extern bool SDL_HIDAPI_ShouldIgnoreDevice(int bus_type, Uint16 vendor_id, Uint16 product_id, Uint16 usage_page, Uint16 usage);
26
27#ifdef SDL_JOYSTICK_HIDAPI
28#ifdef HAVE_LIBUSB
29#define HAVE_ENABLE_GAMECUBE_ADAPTORS
30#endif
31
32#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS
33extern void SDL_EnableGameCubeAdaptors(void);
34#endif
35#endif /* SDL_JOYSTICK_HIDAPI */
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_ios.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_ios.h
new file mode 100644
index 0000000..f58f10d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_ios.h
@@ -0,0 +1,26 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/* The implementation for iOS and tvOS is in a separate .m file */
23#undef HIDAPI_H__
24#include "hidapi/hidapi.h"
25#define HAVE_PLATFORM_BACKEND 1
26#define udev_ctx 1
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_libusb.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_libusb.h
new file mode 100644
index 0000000..ed8b4a3
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_libusb.h
@@ -0,0 +1,134 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/* Define standard library functions in terms of SDL */
23
24/* #pragma push_macro/pop_macro works correctly only as of gcc >= 4.4.3
25 clang-3.0 _seems_ to be OK. */
26#pragma push_macro("calloc")
27#pragma push_macro("malloc")
28#pragma push_macro("realloc")
29#pragma push_macro("free")
30#pragma push_macro("iconv_t")
31#pragma push_macro("iconv")
32#pragma push_macro("iconv_open")
33#pragma push_macro("iconv_close")
34#pragma push_macro("setlocale")
35#pragma push_macro("snprintf")
36#pragma push_macro("strcmp")
37#pragma push_macro("strdup")
38#pragma push_macro("strncpy")
39#pragma push_macro("tolower")
40#pragma push_macro("wcscmp")
41#pragma push_macro("wcsdup")
42#pragma push_macro("wcsncpy")
43
44#undef calloc
45#undef malloc
46#undef realloc
47#undef free
48#undef iconv_t
49#undef iconv
50#undef iconv_open
51#undef iconv_close
52#undef setlocale
53#undef snprintf
54#undef strcmp
55#undef strdup
56#undef strncpy
57#undef tolower
58#undef wcscmp
59#undef wcsdup
60#undef wcsncpy
61
62#define calloc SDL_calloc
63#define malloc SDL_malloc
64#define realloc SDL_realloc
65#define free SDL_free
66#define iconv_t SDL_iconv_t
67#ifndef ICONV_CONST
68#define ICONV_CONST
69#define UNDEF_ICONV_CONST
70#endif
71#define iconv(a,b,c,d,e) SDL_iconv(a, (const char **)b, c, d, e)
72#define iconv_open SDL_iconv_open
73#define iconv_close SDL_iconv_close
74#define setlocale(X, Y) NULL
75#define snprintf SDL_snprintf
76#define strcmp SDL_strcmp
77#define strdup SDL_strdup
78#define strncpy SDL_strlcpy
79#define tolower SDL_tolower
80#define wcscmp SDL_wcscmp
81#define wcsdup SDL_wcsdup
82#define wcsncpy SDL_wcslcpy
83
84
85#ifndef SDL_PLATFORM_FREEBSD
86/* this is awkwardly inlined, so we need to re-implement it here
87 * so we can override the libusb_control_transfer call */
88static int SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
89 uint8_t descriptor_index, uint16_t lang_id,
90 unsigned char *data, int length)
91{
92 return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN | 0x0, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | descriptor_index, lang_id,
93 data, (uint16_t)length, 1000); /* Endpoint 0 IN */
94}
95#define libusb_get_string_descriptor SDL_libusb_get_string_descriptor
96#endif /* SDL_PLATFORM_FREEBSD */
97
98#define HIDAPI_THREAD_MODEL_INCLUDE "hidapi_thread_sdl.h"
99#ifndef LIBUSB_API_VERSION
100#ifdef LIBUSBX_API_VERSION
101#define LIBUSB_API_VERSION LIBUSBX_API_VERSION
102#else
103#define LIBUSB_API_VERSION 0x0
104#endif
105#endif
106/* we need libusb >= 1.0.16 because of libusb_get_port_numbers */
107/* we don't need libusb_wrap_sys_device: */
108#define HIDAPI_TARGET_LIBUSB_API_VERSION 0x01000102
109
110#undef HIDAPI_H__
111#include "libusb/hid.c"
112
113/* restore libc function macros */
114#ifdef UNDEF_ICONV_CONST
115#undef ICONV_CONST
116#undef UNDEF_ICONV_CONST
117#endif
118#pragma pop_macro("calloc")
119#pragma pop_macro("malloc")
120#pragma pop_macro("realloc")
121#pragma pop_macro("free")
122#pragma pop_macro("iconv_t")
123#pragma pop_macro("iconv")
124#pragma pop_macro("iconv_open")
125#pragma pop_macro("iconv_close")
126#pragma pop_macro("setlocale")
127#pragma pop_macro("snprintf")
128#pragma pop_macro("strcmp")
129#pragma pop_macro("strdup")
130#pragma pop_macro("strncpy")
131#pragma pop_macro("tolower")
132#pragma pop_macro("wcscmp")
133#pragma pop_macro("wcsdup")
134#pragma pop_macro("wcsncpy")
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_linux.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_linux.h
new file mode 100644
index 0000000..29723d7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_linux.h
@@ -0,0 +1,47 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#ifdef SDL_USE_LIBUDEV
23static const SDL_UDEV_Symbols *udev_ctx = NULL;
24
25#define udev_device_get_devnode udev_ctx->udev_device_get_devnode
26#define udev_device_get_parent_with_subsystem_devtype udev_ctx->udev_device_get_parent_with_subsystem_devtype
27#define udev_device_get_sysattr_value udev_ctx->udev_device_get_sysattr_value
28#define udev_device_get_syspath udev_ctx->udev_device_get_syspath
29#define udev_device_new_from_devnum udev_ctx->udev_device_new_from_devnum
30#define udev_device_new_from_syspath udev_ctx->udev_device_new_from_syspath
31#define udev_device_unref udev_ctx->udev_device_unref
32#define udev_enumerate_add_match_subsystem udev_ctx->udev_enumerate_add_match_subsystem
33#define udev_enumerate_get_list_entry udev_ctx->udev_enumerate_get_list_entry
34#define udev_enumerate_new udev_ctx->udev_enumerate_new
35#define udev_enumerate_scan_devices udev_ctx->udev_enumerate_scan_devices
36#define udev_enumerate_unref udev_ctx->udev_enumerate_unref
37#define udev_list_entry_get_name udev_ctx->udev_list_entry_get_name
38#define udev_list_entry_get_next udev_ctx->udev_list_entry_get_next
39#define udev_new udev_ctx->udev_new
40#define udev_unref udev_ctx->udev_unref
41
42#undef HIDAPI_H__
43#define HIDAPI_ALLOW_BUILD_WORKAROUND_KERNEL_2_6_39
44#include "linux/hid.c"
45#define HAVE_PLATFORM_BACKEND 1
46
47#endif /* SDL_USE_LIBUDEV */
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_mac.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_mac.h
new file mode 100644
index 0000000..820b67d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_mac.h
@@ -0,0 +1,25 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#undef HIDAPI_H__
23#include "mac/hid.c"
24#define HAVE_PLATFORM_BACKEND 1
25#define udev_ctx 1
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_netbsd.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_netbsd.h
new file mode 100644
index 0000000..1b39e22
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_netbsd.h
@@ -0,0 +1,25 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#undef HIDAPI_H__
23#include "netbsd/hid.c"
24#define HAVE_PLATFORM_BACKEND 1
25#define udev_ctx 1
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_steamxbox.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_steamxbox.h
new file mode 100644
index 0000000..b6294a3
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_steamxbox.h
@@ -0,0 +1,23 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#undef HIDAPI_H__
23#include "steamxbox/hid.c"
diff --git a/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_windows.h b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_windows.h
new file mode 100644
index 0000000..c29122b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/SDL_hidapi_windows.h
@@ -0,0 +1,82 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/* Define standard library functions in terms of SDL */
23
24/* #pragma push_macro/pop_macro works correctly only as of gcc >= 4.4.3
25 clang-3.0 _seems_ to be OK. */
26#pragma push_macro("calloc")
27#pragma push_macro("free")
28#pragma push_macro("malloc")
29#pragma push_macro("memcmp")
30#pragma push_macro("swprintf")
31#pragma push_macro("towupper")
32#pragma push_macro("wcscmp")
33#pragma push_macro("_wcsdup")
34#pragma push_macro("wcslen")
35#pragma push_macro("wcsncpy")
36#pragma push_macro("wcsstr")
37#pragma push_macro("wcstol")
38
39#undef calloc
40#undef free
41#undef malloc
42#undef memcmp
43#undef swprintf
44#undef towupper
45#undef wcscmp
46#undef _wcsdup
47#undef wcslen
48#undef wcsncpy
49#undef wcsstr
50#undef wcstol
51
52#define calloc SDL_calloc
53#define free SDL_free
54#define malloc SDL_malloc
55#define memcmp SDL_memcmp
56#define swprintf SDL_swprintf
57#define towupper (wchar_t)SDL_toupper
58#define wcscmp SDL_wcscmp
59#define _wcsdup SDL_wcsdup
60#define wcslen SDL_wcslen
61#define wcsncpy SDL_wcslcpy
62#define wcsstr SDL_wcsstr
63#define wcstol SDL_wcstol
64
65#undef HIDAPI_H__
66#include "windows/hid.c"
67#define HAVE_PLATFORM_BACKEND 1
68#define udev_ctx 1
69
70/* restore libc function macros */
71#pragma pop_macro("calloc")
72#pragma pop_macro("free")
73#pragma pop_macro("malloc")
74#pragma pop_macro("memcmp")
75#pragma pop_macro("swprintf")
76#pragma pop_macro("towupper")
77#pragma pop_macro("wcscmp")
78#pragma pop_macro("_wcsdup")
79#pragma pop_macro("wcslen")
80#pragma pop_macro("wcsncpy")
81#pragma pop_macro("wcsstr")
82#pragma pop_macro("wcstol")
diff --git a/contrib/SDL-3.2.8/src/hidapi/VERSION b/contrib/SDL-3.2.8/src/hidapi/VERSION
new file mode 100644
index 0000000..0548fb4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/VERSION
@@ -0,0 +1 @@
0.14.0 \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/android/hid.cpp b/contrib/SDL-3.2.8/src/hidapi/android/hid.cpp
new file mode 100644
index 0000000..887390e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/android/hid.cpp
@@ -0,0 +1,1477 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 2022 Valve Corporation
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23// Purpose: A wrapper implementing "HID" API for Android
24//
25// This layer glues the hidapi API to Android's USB and BLE stack.
26
27#include "hid.h"
28
29// Common to stub version and non-stub version of functions
30#include <jni.h>
31#include <android/log.h>
32
33#define TAG "hidapi"
34
35// Have error log always available
36#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
37
38#ifdef DEBUG
39#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
40#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
41#else
42#define LOGV(...)
43#define LOGD(...)
44#endif
45
46#define SDL_JAVA_PREFIX org_libsdl_app
47#define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function)
48#define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function
49#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
50
51
52#ifndef SDL_HIDAPI_DISABLED
53
54extern "C" {
55#include "../SDL_hidapi_c.h"
56}
57#include "../../core/android/SDL_android.h"
58
59#define hid_close PLATFORM_hid_close
60#define hid_device PLATFORM_hid_device
61#define hid_device_ PLATFORM_hid_device_
62#define hid_enumerate PLATFORM_hid_enumerate
63#define hid_error PLATFORM_hid_error
64#define hid_exit PLATFORM_hid_exit
65#define hid_free_enumeration PLATFORM_hid_free_enumeration
66#define hid_get_device_info PLATFORM_hid_get_device_info
67#define hid_get_feature_report PLATFORM_hid_get_feature_report
68#define hid_get_indexed_string PLATFORM_hid_get_indexed_string
69#define hid_get_input_report PLATFORM_hid_get_input_report
70#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string
71#define hid_get_product_string PLATFORM_hid_get_product_string
72#define hid_get_report_descriptor PLATFORM_hid_get_report_descriptor
73#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string
74#define hid_init PLATFORM_hid_init
75#define hid_open_path PLATFORM_hid_open_path
76#define hid_open PLATFORM_hid_open
77#define hid_read PLATFORM_hid_read
78#define hid_read_timeout PLATFORM_hid_read_timeout
79#define hid_send_feature_report PLATFORM_hid_send_feature_report
80#define hid_set_nonblocking PLATFORM_hid_set_nonblocking
81#define hid_version PLATFORM_hid_version
82#define hid_version_str PLATFORM_hid_version_str
83#define hid_write PLATFORM_hid_write
84
85#include <pthread.h>
86#include <errno.h> // For ETIMEDOUT and ECONNRESET
87#include <stdlib.h> // For malloc() and free()
88
89#include "../hidapi/hidapi.h"
90
91typedef uint32_t uint32;
92typedef uint64_t uint64;
93
94
95struct hid_device_
96{
97 int m_nId;
98 int m_nDeviceRefCount;
99};
100
101template<class T>
102class hid_device_ref
103{
104public:
105 hid_device_ref( T *pObject = nullptr ) : m_pObject( nullptr )
106 {
107 SetObject( pObject );
108 }
109
110 hid_device_ref( const hid_device_ref &rhs ) : m_pObject( nullptr )
111 {
112 SetObject( rhs.GetObject() );
113 }
114
115 ~hid_device_ref()
116 {
117 SetObject( nullptr );
118 }
119
120 void SetObject( T *pObject )
121 {
122 if ( m_pObject && m_pObject->DecrementRefCount() == 0 )
123 {
124 delete m_pObject;
125 }
126
127 m_pObject = pObject;
128
129 if ( m_pObject )
130 {
131 m_pObject->IncrementRefCount();
132 }
133 }
134
135 hid_device_ref &operator =( T *pObject )
136 {
137 SetObject( pObject );
138 return *this;
139 }
140
141 hid_device_ref &operator =( const hid_device_ref &rhs )
142 {
143 SetObject( rhs.GetObject() );
144 return *this;
145 }
146
147 T *GetObject() const
148 {
149 return m_pObject;
150 }
151
152 T* operator->() const
153 {
154 return m_pObject;
155 }
156
157 operator bool() const
158 {
159 return ( m_pObject != nullptr );
160 }
161
162private:
163 T *m_pObject;
164};
165
166class hid_mutex_guard
167{
168public:
169 hid_mutex_guard( pthread_mutex_t *pMutex ) : m_pMutex( pMutex )
170 {
171 pthread_mutex_lock( m_pMutex );
172 }
173 ~hid_mutex_guard()
174 {
175 pthread_mutex_unlock( m_pMutex );
176 }
177
178private:
179 pthread_mutex_t *m_pMutex;
180};
181
182class hid_buffer
183{
184public:
185 hid_buffer() : m_pData( nullptr ), m_nSize( 0 ), m_nAllocated( 0 )
186 {
187 }
188
189 hid_buffer( const uint8_t *pData, size_t nSize ) : m_pData( nullptr ), m_nSize( 0 ), m_nAllocated( 0 )
190 {
191 assign( pData, nSize );
192 }
193
194 ~hid_buffer()
195 {
196 delete[] m_pData;
197 }
198
199 void assign( const uint8_t *pData, size_t nSize )
200 {
201 if ( nSize > m_nAllocated )
202 {
203 delete[] m_pData;
204 m_pData = new uint8_t[ nSize ];
205 m_nAllocated = nSize;
206 }
207
208 m_nSize = nSize;
209 SDL_memcpy( m_pData, pData, nSize );
210 }
211
212 void clear()
213 {
214 m_nSize = 0;
215 }
216
217 size_t size() const
218 {
219 return m_nSize;
220 }
221
222 const uint8_t *data() const
223 {
224 return m_pData;
225 }
226
227private:
228 uint8_t *m_pData;
229 size_t m_nSize;
230 size_t m_nAllocated;
231};
232
233class hid_buffer_pool
234{
235public:
236 hid_buffer_pool() : m_nSize( 0 ), m_pHead( nullptr ), m_pTail( nullptr ), m_pFree( nullptr )
237 {
238 }
239
240 ~hid_buffer_pool()
241 {
242 clear();
243
244 while ( m_pFree )
245 {
246 hid_buffer_entry *pEntry = m_pFree;
247 m_pFree = m_pFree->m_pNext;
248 delete pEntry;
249 }
250 }
251
252 size_t size() const { return m_nSize; }
253
254 const hid_buffer &front() const { return m_pHead->m_buffer; }
255
256 void pop_front()
257 {
258 hid_buffer_entry *pEntry = m_pHead;
259 if ( pEntry )
260 {
261 m_pHead = pEntry->m_pNext;
262 if ( !m_pHead )
263 {
264 m_pTail = nullptr;
265 }
266 pEntry->m_pNext = m_pFree;
267 m_pFree = pEntry;
268 --m_nSize;
269 }
270 }
271
272 void emplace_back( const uint8_t *pData, size_t nSize )
273 {
274 hid_buffer_entry *pEntry;
275
276 if ( m_pFree )
277 {
278 pEntry = m_pFree;
279 m_pFree = m_pFree->m_pNext;
280 }
281 else
282 {
283 pEntry = new hid_buffer_entry;
284 }
285 pEntry->m_pNext = nullptr;
286
287 if ( m_pTail )
288 {
289 m_pTail->m_pNext = pEntry;
290 }
291 else
292 {
293 m_pHead = pEntry;
294 }
295 m_pTail = pEntry;
296
297 pEntry->m_buffer.assign( pData, nSize );
298 ++m_nSize;
299 }
300
301 void clear()
302 {
303 while ( size() > 0 )
304 {
305 pop_front();
306 }
307 }
308
309private:
310 struct hid_buffer_entry
311 {
312 hid_buffer m_buffer;
313 hid_buffer_entry *m_pNext;
314 };
315
316 size_t m_nSize;
317 hid_buffer_entry *m_pHead;
318 hid_buffer_entry *m_pTail;
319 hid_buffer_entry *m_pFree;
320};
321
322static jbyteArray NewByteArray( JNIEnv* env, const uint8_t *pData, size_t nDataLen )
323{
324 jbyteArray array = env->NewByteArray( (jsize)nDataLen );
325 jbyte *pBuf = env->GetByteArrayElements( array, NULL );
326 SDL_memcpy( pBuf, pData, nDataLen );
327 env->ReleaseByteArrayElements( array, pBuf, 0 );
328
329 return array;
330}
331
332static char *CreateStringFromJString( JNIEnv *env, const jstring &sString )
333{
334 size_t nLength = env->GetStringUTFLength( sString );
335 const char *pjChars = env->GetStringUTFChars( sString, NULL );
336 char *psString = (char*)malloc( nLength + 1 );
337 SDL_memcpy( psString, pjChars, nLength );
338 psString[ nLength ] = '\0';
339 env->ReleaseStringUTFChars( sString, pjChars );
340 return psString;
341}
342
343static wchar_t *CreateWStringFromJString( JNIEnv *env, const jstring &sString )
344{
345 size_t nLength = env->GetStringLength( sString );
346 const jchar *pjChars = env->GetStringChars( sString, NULL );
347 wchar_t *pwString = (wchar_t*)malloc( ( nLength + 1 ) * sizeof( wchar_t ) );
348 wchar_t *pwChars = pwString;
349 for ( size_t iIndex = 0; iIndex < nLength; ++iIndex )
350 {
351 pwChars[ iIndex ] = pjChars[ iIndex ];
352 }
353 pwString[ nLength ] = '\0';
354 env->ReleaseStringChars( sString, pjChars );
355 return pwString;
356}
357
358static wchar_t *CreateWStringFromWString( const wchar_t *pwSrc )
359{
360 size_t nLength = SDL_wcslen( pwSrc );
361 wchar_t *pwString = (wchar_t*)malloc( ( nLength + 1 ) * sizeof( wchar_t ) );
362 SDL_memcpy( pwString, pwSrc, nLength * sizeof( wchar_t ) );
363 pwString[ nLength ] = '\0';
364 return pwString;
365}
366
367static hid_device_info *CopyHIDDeviceInfo( const hid_device_info *pInfo )
368{
369 hid_device_info *pCopy = new hid_device_info;
370 *pCopy = *pInfo;
371 pCopy->path = SDL_strdup( pInfo->path );
372 pCopy->product_string = CreateWStringFromWString( pInfo->product_string );
373 pCopy->manufacturer_string = CreateWStringFromWString( pInfo->manufacturer_string );
374 pCopy->serial_number = CreateWStringFromWString( pInfo->serial_number );
375 return pCopy;
376}
377
378static void FreeHIDDeviceInfo( hid_device_info *pInfo )
379{
380 free( pInfo->path );
381 free( pInfo->serial_number );
382 free( pInfo->manufacturer_string );
383 free( pInfo->product_string );
384 delete pInfo;
385}
386
387static jclass g_HIDDeviceManagerCallbackClass;
388static jobject g_HIDDeviceManagerCallbackHandler;
389static jmethodID g_midHIDDeviceManagerInitialize;
390static jmethodID g_midHIDDeviceManagerOpen;
391static jmethodID g_midHIDDeviceManagerWriteReport;
392static jmethodID g_midHIDDeviceManagerReadReport;
393static jmethodID g_midHIDDeviceManagerClose;
394static bool g_initialized = false;
395
396static uint64_t get_timespec_ms( const struct timespec &ts )
397{
398 return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
399}
400
401static void ExceptionCheck( JNIEnv *env, const char *pszClassName, const char *pszMethodName )
402{
403 if ( env->ExceptionCheck() )
404 {
405 // Get our exception
406 jthrowable jExcept = env->ExceptionOccurred();
407
408 // Clear the exception so we can call JNI again
409 env->ExceptionClear();
410
411 // Get our exception message
412 jclass jExceptClass = env->GetObjectClass( jExcept );
413 jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" );
414 jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) );
415 const char *pszMessage = env->GetStringUTFChars( jMessage, NULL );
416
417 // ...and log it.
418 LOGE( "%s%s%s threw an exception: %s",
419 pszClassName ? pszClassName : "",
420 pszClassName ? "::" : "",
421 pszMethodName, pszMessage );
422
423 // Cleanup
424 env->ReleaseStringUTFChars( jMessage, pszMessage );
425 env->DeleteLocalRef( jMessage );
426 env->DeleteLocalRef( jExceptClass );
427 env->DeleteLocalRef( jExcept );
428 }
429}
430
431class CHIDDevice
432{
433public:
434 CHIDDevice( int nDeviceID, hid_device_info *pInfo )
435 {
436 m_nId = nDeviceID;
437 m_pInfo = pInfo;
438
439 // The Bluetooth Steam Controller needs special handling
440 const int VALVE_USB_VID = 0x28DE;
441 const int D0G_BLE2_PID = 0x1106;
442 if ( pInfo->vendor_id == VALVE_USB_VID && pInfo->product_id == D0G_BLE2_PID )
443 {
444 m_bIsBLESteamController = true;
445 }
446 }
447
448 ~CHIDDevice()
449 {
450 FreeHIDDeviceInfo( m_pInfo );
451
452 // Note that we don't delete m_pDevice, as the app may still have a reference to it
453 }
454
455 int IncrementRefCount()
456 {
457 int nValue;
458 pthread_mutex_lock( &m_refCountLock );
459 nValue = ++m_nRefCount;
460 pthread_mutex_unlock( &m_refCountLock );
461 return nValue;
462 }
463
464 int DecrementRefCount()
465 {
466 int nValue;
467 pthread_mutex_lock( &m_refCountLock );
468 nValue = --m_nRefCount;
469 pthread_mutex_unlock( &m_refCountLock );
470 return nValue;
471 }
472
473 int GetId()
474 {
475 return m_nId;
476 }
477
478 hid_device_info *GetDeviceInfo()
479 {
480 return m_pInfo;
481 }
482
483 hid_device *GetDevice()
484 {
485 return m_pDevice;
486 }
487
488 void ExceptionCheck( JNIEnv *env, const char *pszMethodName )
489 {
490 ::ExceptionCheck( env, "CHIDDevice", pszMethodName );
491 }
492
493 bool BOpen()
494 {
495 JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
496
497 if ( !g_HIDDeviceManagerCallbackHandler )
498 {
499 LOGV( "Device open without callback handler" );
500 return false;
501 }
502
503 if ( m_bIsWaitingForOpen )
504 {
505 SDL_SetError( "Waiting for permission" );
506 return false;
507 }
508
509 if ( !m_bOpenResult )
510 {
511 m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
512 ExceptionCheck( env, "BOpen" );
513
514 if ( m_bIsWaitingForOpen )
515 {
516 LOGV( "Device open waiting for permission" );
517 SDL_SetError( "Waiting for permission" );
518 m_bWasOpenPending = true;
519 return false;
520 }
521
522 if ( !m_bOpenResult )
523 {
524 LOGV( "Device open failed" );
525 SDL_SetError( "Device open failed" );
526 return false;
527 }
528 }
529
530 m_pDevice = new hid_device;
531 m_pDevice->m_nId = m_nId;
532 m_pDevice->m_nDeviceRefCount = 1;
533 LOGD("Creating device %d (%p), refCount = 1\n", m_pDevice->m_nId, m_pDevice);
534
535 return true;
536 }
537
538 void SetOpenPending()
539 {
540 m_bIsWaitingForOpen = true;
541 }
542
543 bool BOpenPending() const
544 {
545 return m_bIsWaitingForOpen;
546 }
547
548 void SetWasOpenPending( bool bState )
549 {
550 m_bWasOpenPending = bState;
551 }
552
553 bool BWasOpenPending() const
554 {
555 return m_bWasOpenPending;
556 }
557
558 void SetOpenResult( bool bResult )
559 {
560 if ( m_bIsWaitingForOpen )
561 {
562 m_bOpenResult = bResult;
563 m_bIsWaitingForOpen = false;
564
565 if ( m_bOpenResult )
566 {
567 LOGV( "Device open succeeded" );
568 }
569 else
570 {
571 LOGV( "Device open failed" );
572 }
573 }
574 }
575
576 bool BOpenResult() const
577 {
578 return m_bOpenResult;
579 }
580
581 void ProcessInput( const uint8_t *pBuf, size_t nBufSize )
582 {
583 hid_mutex_guard l( &m_dataLock );
584
585 size_t MAX_REPORT_QUEUE_SIZE = 16;
586 if ( m_vecData.size() >= MAX_REPORT_QUEUE_SIZE )
587 {
588 m_vecData.pop_front();
589 }
590 m_vecData.emplace_back( pBuf, nBufSize );
591 }
592
593 int GetInput( unsigned char *data, size_t length )
594 {
595 hid_mutex_guard l( &m_dataLock );
596
597 if ( m_vecData.size() == 0 )
598 {
599// LOGV( "hid_read_timeout no data available" );
600 return 0;
601 }
602
603 const hid_buffer &buffer = m_vecData.front();
604 size_t nDataLen = buffer.size() > length ? length : buffer.size();
605 if ( m_bIsBLESteamController )
606 {
607 data[0] = 0x03;
608 SDL_memcpy( data + 1, buffer.data(), nDataLen );
609 ++nDataLen;
610 }
611 else
612 {
613 SDL_memcpy( data, buffer.data(), nDataLen );
614 }
615 m_vecData.pop_front();
616
617// LOGV("Read %u bytes", nDataLen);
618// LOGV("%02x %02x %02x %02x %02x %02x %02x %02x ....",
619// data[0], data[1], data[2], data[3],
620// data[4], data[5], data[6], data[7]);
621
622 return (int)nDataLen;
623 }
624
625 int WriteReport( const unsigned char *pData, size_t nDataLen, bool bFeature )
626 {
627 JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
628
629 if ( !g_HIDDeviceManagerCallbackHandler )
630 {
631 LOGV( "WriteReport without callback handler" );
632 return -1;
633 }
634
635 jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
636 int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerWriteReport, m_nId, pBuf, bFeature );
637 ExceptionCheck( env, "WriteReport" );
638 env->DeleteLocalRef( pBuf );
639 return nRet;
640 }
641
642 void ProcessReportResponse( const uint8_t *pBuf, size_t nBufSize )
643 {
644 hid_mutex_guard cvl( &m_cvLock );
645 if ( m_bIsWaitingForReportResponse )
646 {
647 m_reportResponse.assign( pBuf, nBufSize );
648
649 m_bIsWaitingForReportResponse = false;
650 m_nReportResponseError = 0;
651 pthread_cond_signal( &m_cv );
652 }
653 }
654
655 int ReadReport( unsigned char *pData, size_t nDataLen, bool bFeature )
656 {
657 JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
658
659 if ( !g_HIDDeviceManagerCallbackHandler )
660 {
661 LOGV( "ReadReport without callback handler" );
662 return -1;
663 }
664
665 {
666 hid_mutex_guard cvl( &m_cvLock );
667 if ( m_bIsWaitingForReportResponse )
668 {
669 LOGV( "Get feature report already ongoing... bail" );
670 return -1; // Read already ongoing, we currently do not serialize, TODO
671 }
672 m_bIsWaitingForReportResponse = true;
673 }
674
675 jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
676 int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerReadReport, m_nId, pBuf, bFeature ) ? 0 : -1;
677 ExceptionCheck( env, "ReadReport" );
678 env->DeleteLocalRef( pBuf );
679 if ( nRet < 0 )
680 {
681 LOGV( "ReadReport failed" );
682 m_bIsWaitingForReportResponse = false;
683 return -1;
684 }
685
686 {
687 hid_mutex_guard cvl( &m_cvLock );
688 if ( m_bIsWaitingForReportResponse )
689 {
690 LOGV("=== Going to sleep" );
691 // Wait in CV until we are no longer waiting for a feature report.
692 const int FEATURE_REPORT_TIMEOUT_SECONDS = 2;
693 struct timespec ts, endtime;
694 clock_gettime( CLOCK_REALTIME, &ts );
695 endtime = ts;
696 endtime.tv_sec += FEATURE_REPORT_TIMEOUT_SECONDS;
697 do
698 {
699 if ( pthread_cond_timedwait( &m_cv, &m_cvLock, &endtime ) != 0 )
700 {
701 break;
702 }
703 }
704 while ( m_bIsWaitingForReportResponse && get_timespec_ms( ts ) < get_timespec_ms( endtime ) );
705
706 // We are back
707 if ( m_bIsWaitingForReportResponse )
708 {
709 m_nReportResponseError = -ETIMEDOUT;
710 m_bIsWaitingForReportResponse = false;
711 }
712 LOGV( "=== Got feature report err=%d", m_nReportResponseError );
713 if ( m_nReportResponseError != 0 )
714 {
715 return m_nReportResponseError;
716 }
717 }
718
719 size_t uBytesToCopy = m_reportResponse.size() > nDataLen ? nDataLen : m_reportResponse.size();
720 SDL_memcpy( pData, m_reportResponse.data(), uBytesToCopy );
721 m_reportResponse.clear();
722 LOGV( "=== Got %zu bytes", uBytesToCopy );
723
724 return (int)uBytesToCopy;
725 }
726 }
727
728 void Close( bool bDeleteDevice )
729 {
730 JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
731
732 if ( g_HIDDeviceManagerCallbackHandler )
733 {
734 if ( !m_bIsWaitingForOpen && m_bOpenResult )
735 {
736 env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
737 ExceptionCheck( env, "Close" );
738 }
739 }
740
741 hid_mutex_guard dataLock( &m_dataLock );
742 m_vecData.clear();
743
744 // Clean and release pending feature report reads
745 hid_mutex_guard cvLock( &m_cvLock );
746 m_reportResponse.clear();
747 m_bIsWaitingForReportResponse = false;
748 m_nReportResponseError = -ECONNRESET;
749 pthread_cond_broadcast( &m_cv );
750
751 m_bOpenResult = false;
752
753 if ( bDeleteDevice )
754 {
755 delete m_pDevice;
756 m_pDevice = nullptr;
757 }
758 }
759
760private:
761 pthread_mutex_t m_refCountLock = PTHREAD_MUTEX_INITIALIZER;
762 int m_nRefCount = 0;
763 int m_nId = 0;
764 hid_device_info *m_pInfo = nullptr;
765 hid_device *m_pDevice = nullptr;
766 bool m_bIsBLESteamController = false;
767
768 pthread_mutex_t m_dataLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access m_vecData
769 hid_buffer_pool m_vecData;
770
771 // For handling get_feature_report
772 pthread_mutex_t m_cvLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access any variables below
773 pthread_cond_t m_cv = PTHREAD_COND_INITIALIZER;
774 bool m_bIsWaitingForOpen = false;
775 bool m_bWasOpenPending = false;
776 bool m_bOpenResult = false;
777 bool m_bIsWaitingForReportResponse = false;
778 int m_nReportResponseError = 0;
779 hid_buffer m_reportResponse;
780
781public:
782 hid_device_ref<CHIDDevice> next;
783};
784
785class CHIDDevice;
786static pthread_mutex_t g_DevicesMutex = PTHREAD_MUTEX_INITIALIZER;
787static pthread_mutex_t g_DevicesRefCountMutex = PTHREAD_MUTEX_INITIALIZER;
788static hid_device_ref<CHIDDevice> g_Devices;
789
790static hid_device_ref<CHIDDevice> FindDevice( int nDeviceId )
791{
792 hid_device_ref<CHIDDevice> pDevice;
793
794 hid_mutex_guard l( &g_DevicesMutex );
795 for ( pDevice = g_Devices; pDevice; pDevice = pDevice->next )
796 {
797 if ( pDevice->GetId() == nDeviceId )
798 {
799 break;
800 }
801 }
802 return pDevice;
803}
804
805
806extern "C"
807JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
808
809extern "C"
810JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
811
812extern "C"
813JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol, bool bBluetooth );
814
815extern "C"
816JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);
817
818extern "C"
819JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);
820
821extern "C"
822JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);
823
824extern "C"
825JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
826
827extern "C"
828JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReportResponse)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
829
830
831extern "C"
832JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
833{
834 LOGV( "HIDDeviceRegisterCallback()");
835
836 if ( g_HIDDeviceManagerCallbackHandler != NULL )
837 {
838 env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
839 g_HIDDeviceManagerCallbackClass = NULL;
840 env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
841 g_HIDDeviceManagerCallbackHandler = NULL;
842 }
843
844 g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( thiz );
845 jclass objClass = env->GetObjectClass( thiz );
846 if ( objClass )
847 {
848 g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef( objClass ) );
849 g_midHIDDeviceManagerInitialize = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "initialize", "(ZZ)Z" );
850 if ( !g_midHIDDeviceManagerInitialize )
851 {
852 __android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing initialize" );
853 }
854 g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" );
855 if ( !g_midHIDDeviceManagerOpen )
856 {
857 __android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing openDevice" );
858 }
859 g_midHIDDeviceManagerWriteReport = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "writeReport", "(I[BZ)I" );
860 if ( !g_midHIDDeviceManagerWriteReport )
861 {
862 __android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing writeReport" );
863 }
864 g_midHIDDeviceManagerReadReport = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "readReport", "(I[BZ)Z" );
865 if ( !g_midHIDDeviceManagerReadReport )
866 {
867 __android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing getFeatureReport" );
868 }
869 g_midHIDDeviceManagerClose = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "closeDevice", "(I)V" );
870 if ( !g_midHIDDeviceManagerClose )
871 {
872 __android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing closeDevice" );
873 }
874 env->DeleteLocalRef( objClass );
875 }
876}
877
878extern "C"
879JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
880{
881 LOGV("HIDDeviceReleaseCallback");
882 if ( env->IsSameObject( thiz, g_HIDDeviceManagerCallbackHandler ) )
883 {
884 env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
885 g_HIDDeviceManagerCallbackClass = NULL;
886 env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
887 g_HIDDeviceManagerCallbackHandler = NULL;
888 g_initialized = false;
889 }
890}
891
892extern "C"
893JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol, bool bBluetooth )
894{
895 LOGV( "HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface );
896
897 hid_device_info *pInfo = new hid_device_info;
898 SDL_memset( pInfo, 0, sizeof( *pInfo ) );
899 pInfo->path = CreateStringFromJString( env, sIdentifier );
900 pInfo->vendor_id = nVendorId;
901 pInfo->product_id = nProductId;
902 pInfo->serial_number = CreateWStringFromJString( env, sSerialNumber );
903 pInfo->release_number = nReleaseNumber;
904 pInfo->manufacturer_string = CreateWStringFromJString( env, sManufacturer );
905 pInfo->product_string = CreateWStringFromJString( env, sProduct );
906 pInfo->interface_number = nInterface;
907 pInfo->interface_class = nInterfaceClass;
908 pInfo->interface_subclass = nInterfaceSubclass;
909 pInfo->interface_protocol = nInterfaceProtocol;
910 if ( bBluetooth )
911 {
912 pInfo->bus_type = HID_API_BUS_BLUETOOTH;
913 }
914 else
915 {
916 pInfo->bus_type = HID_API_BUS_USB;
917 }
918
919 hid_device_ref<CHIDDevice> pDevice( new CHIDDevice( nDeviceID, pInfo ) );
920
921 hid_mutex_guard l( &g_DevicesMutex );
922 hid_device_ref<CHIDDevice> pLast, pCurr;
923 for ( pCurr = g_Devices; pCurr; pLast = pCurr, pCurr = pCurr->next )
924 {
925 continue;
926 }
927 if ( pLast )
928 {
929 pLast->next = pDevice;
930 }
931 else
932 {
933 g_Devices = pDevice;
934 }
935}
936
937extern "C"
938JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID)
939{
940 LOGV( "HIDDeviceOpenPending() id=%d\n", nDeviceID );
941 hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
942 if ( pDevice )
943 {
944 pDevice->SetOpenPending();
945 }
946}
947
948extern "C"
949JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened)
950{
951 LOGV( "HIDDeviceOpenResult() id=%d, result=%s\n", nDeviceID, bOpened ? "true" : "false" );
952 hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
953 if ( pDevice )
954 {
955 pDevice->SetOpenResult( bOpened );
956 }
957}
958
959extern "C"
960JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID)
961{
962 LOGV( "HIDDeviceDisconnected() id=%d\n", nDeviceID );
963 hid_device_ref<CHIDDevice> pDevice;
964 {
965 hid_mutex_guard l( &g_DevicesMutex );
966 hid_device_ref<CHIDDevice> pLast, pCurr;
967 for ( pCurr = g_Devices; pCurr; pLast = pCurr, pCurr = pCurr->next )
968 {
969 if ( pCurr->GetId() == nDeviceID )
970 {
971 pDevice = pCurr;
972
973 if ( pLast )
974 {
975 pLast->next = pCurr->next;
976 }
977 else
978 {
979 g_Devices = pCurr->next;
980 }
981 }
982 }
983 }
984 if ( pDevice )
985 {
986 pDevice->Close( false );
987 }
988}
989
990extern "C"
991JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
992{
993 jbyte *pBuf = env->GetByteArrayElements(value, NULL);
994 jsize nBufSize = env->GetArrayLength(value);
995
996// LOGV( "HIDDeviceInput() id=%d len=%u\n", nDeviceID, nBufSize );
997 hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
998 if ( pDevice )
999 {
1000 pDevice->ProcessInput( reinterpret_cast< const uint8_t* >( pBuf ), nBufSize );
1001 }
1002
1003 env->ReleaseByteArrayElements(value, pBuf, 0);
1004}
1005
1006extern "C"
1007JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReportResponse)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
1008{
1009 jbyte *pBuf = env->GetByteArrayElements(value, NULL);
1010 jsize nBufSize = env->GetArrayLength(value);
1011
1012 LOGV( "HIDDeviceReportResponse() id=%d len=%u\n", nDeviceID, nBufSize );
1013 hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
1014 if ( pDevice )
1015 {
1016 pDevice->ProcessReportResponse( reinterpret_cast< const uint8_t* >( pBuf ), nBufSize );
1017 }
1018
1019 env->ReleaseByteArrayElements(value, pBuf, 0);
1020}
1021
1022//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1023//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1024//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1025
1026extern "C"
1027{
1028
1029static void SDLCALL RequestBluetoothPermissionCallback( void *userdata, const char *permission, bool granted )
1030{
1031 SDL_Log( "Bluetooth permission %s", granted ? "granted" : "denied" );
1032
1033 if ( granted && g_HIDDeviceManagerCallbackHandler )
1034 {
1035 JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
1036
1037 env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, false, true );
1038 }
1039}
1040
1041int hid_init(void)
1042{
1043 if ( !g_initialized && g_HIDDeviceManagerCallbackHandler )
1044 {
1045 // HIDAPI doesn't work well with Android < 4.3
1046 if ( SDL_GetAndroidSDKVersion() >= 18 )
1047 {
1048 JNIEnv *env = (JNIEnv *)SDL_GetAndroidJNIEnv();
1049
1050 env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, true, false );
1051
1052 // Bluetooth is currently only used for Steam Controllers, so check that hint
1053 // before initializing Bluetooth, which will prompt the user for permission.
1054 if ( SDL_GetHintBoolean( SDL_HINT_JOYSTICK_HIDAPI_STEAM, false ) )
1055 {
1056 if ( SDL_GetAndroidSDKVersion() < 31 )
1057 {
1058 env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, false, true );
1059 }
1060 else
1061 {
1062 SDL_Log( "Requesting Bluetooth permission" );
1063 SDL_RequestAndroidPermission( "android.permission.BLUETOOTH_CONNECT", RequestBluetoothPermissionCallback, NULL );
1064 }
1065 }
1066 ExceptionCheck( env, NULL, "hid_init" );
1067 }
1068 g_initialized = true; // Regardless of result, so it's only called once
1069 }
1070 return 0;
1071}
1072
1073struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
1074{
1075 struct hid_device_info *root = NULL;
1076
1077 hid_mutex_guard l( &g_DevicesMutex );
1078 for ( hid_device_ref<CHIDDevice> pDevice = g_Devices; pDevice; pDevice = pDevice->next )
1079 {
1080 // Don't enumerate devices that are currently being opened, we'll re-enumerate them when we're done
1081 // Make sure we skip them at least once, so they get removed and then re-added to the caller's device list
1082 if ( pDevice->BWasOpenPending() )
1083 {
1084 // Don't enumerate devices that failed to open, otherwise the application might try to keep prompting for access
1085 if ( !pDevice->BOpenPending() && pDevice->BOpenResult() )
1086 {
1087 pDevice->SetWasOpenPending( false );
1088 }
1089 continue;
1090 }
1091
1092 const hid_device_info *info = pDevice->GetDeviceInfo();
1093
1094 /* See if there are any devices we should skip in enumeration */
1095 if (SDL_HIDAPI_ShouldIgnoreDevice(HID_API_BUS_UNKNOWN, info->vendor_id, info->product_id, 0, 0)) {
1096 continue;
1097 }
1098
1099 if ( ( vendor_id == 0x0 || info->vendor_id == vendor_id ) &&
1100 ( product_id == 0x0 || info->product_id == product_id ) )
1101 {
1102 hid_device_info *dev = CopyHIDDeviceInfo( info );
1103 dev->next = root;
1104 root = dev;
1105 }
1106 }
1107 return root;
1108}
1109
1110void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
1111{
1112 while ( devs )
1113 {
1114 struct hid_device_info *next = devs->next;
1115 FreeHIDDeviceInfo( devs );
1116 devs = next;
1117 }
1118}
1119
1120HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
1121{
1122 // TODO: Implement
1123 return NULL;
1124}
1125
1126HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
1127{
1128 LOGV( "hid_open_path( %s )", path );
1129
1130 hid_device_ref< CHIDDevice > pDevice;
1131 {
1132 hid_mutex_guard r( &g_DevicesRefCountMutex );
1133 hid_mutex_guard l( &g_DevicesMutex );
1134 for ( hid_device_ref<CHIDDevice> pCurr = g_Devices; pCurr; pCurr = pCurr->next )
1135 {
1136 if ( SDL_strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 )
1137 {
1138 hid_device *pValue = pCurr->GetDevice();
1139 if ( pValue )
1140 {
1141 ++pValue->m_nDeviceRefCount;
1142 LOGD("Incrementing device %d (%p), refCount = %d\n", pValue->m_nId, pValue, pValue->m_nDeviceRefCount);
1143 return pValue;
1144 }
1145
1146 // Hold a shared pointer to the controller for the duration
1147 pDevice = pCurr;
1148 break;
1149 }
1150 }
1151 }
1152 if ( !pDevice )
1153 {
1154 SDL_SetError( "Couldn't find device with path %s", path );
1155 return NULL;
1156 }
1157 if ( pDevice->BOpen() )
1158 {
1159 return pDevice->GetDevice();
1160 }
1161 return NULL;
1162}
1163
1164int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
1165{
1166 if ( device )
1167 {
1168// LOGV( "hid_write id=%d length=%zu", device->m_nId, length );
1169 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1170 if ( pDevice )
1171 {
1172 return pDevice->WriteReport( data, length, false );
1173 }
1174 }
1175 return -1; // Controller was disconnected
1176}
1177
1178static uint32_t getms()
1179{
1180 struct timeval now;
1181
1182 gettimeofday(&now, NULL);
1183 return (uint32_t)(now.tv_sec * 1000 + now.tv_usec / 1000);
1184}
1185
1186static void delayms(uint32_t ms)
1187{
1188 int was_error;
1189
1190 struct timespec elapsed, tv;
1191
1192 /* Set the timeout interval */
1193 elapsed.tv_sec = ms / 1000;
1194 elapsed.tv_nsec = (ms % 1000) * 1000000;
1195 do {
1196 errno = 0;
1197
1198 tv.tv_sec = elapsed.tv_sec;
1199 tv.tv_nsec = elapsed.tv_nsec;
1200 was_error = nanosleep(&tv, &elapsed);
1201 } while (was_error && (errno == EINTR));
1202}
1203
1204int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
1205{
1206 if ( device )
1207 {
1208// LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->m_nId, length, milliseconds );
1209 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1210 if ( pDevice )
1211 {
1212 int nResult = pDevice->GetInput( data, length );
1213 if ( nResult == 0 && milliseconds > 0 )
1214 {
1215 uint32_t start = getms();
1216 do
1217 {
1218 delayms( 1 );
1219 nResult = pDevice->GetInput( data, length );
1220 } while ( nResult == 0 && ( getms() - start ) < milliseconds );
1221 }
1222 return nResult;
1223 }
1224 LOGV( "controller was disconnected" );
1225 }
1226 return -1; // Controller was disconnected
1227}
1228
1229// TODO: Implement blocking
1230int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
1231{
1232// LOGV( "hid_read id=%d length=%zu", device->m_nId, length );
1233 return hid_read_timeout( device, data, length, 0 );
1234}
1235
1236// TODO: Implement?
1237int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
1238{
1239 return -1;
1240}
1241
1242int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
1243{
1244 if ( device )
1245 {
1246 LOGV( "hid_send_feature_report id=%d length=%zu", device->m_nId, length );
1247 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1248 if ( pDevice )
1249 {
1250 return pDevice->WriteReport( data, length, true );
1251 }
1252 }
1253 return -1; // Controller was disconnected
1254}
1255
1256
1257// Synchronous operation. Will block until completed.
1258int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
1259{
1260 if ( device )
1261 {
1262 LOGV( "hid_get_feature_report id=%d length=%zu", device->m_nId, length );
1263 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1264 if ( pDevice )
1265 {
1266 return pDevice->ReadReport( data, length, true );
1267 }
1268 }
1269 return -1; // Controller was disconnected
1270}
1271
1272
1273// Synchronous operation. Will block until completed.
1274int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *device, unsigned char *data, size_t length)
1275{
1276 if ( device )
1277 {
1278 LOGV( "hid_get_input_report id=%d length=%zu", device->m_nId, length );
1279 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1280 if ( pDevice )
1281 {
1282 return pDevice->ReadReport( data, length, false );
1283 }
1284 }
1285 return -1; // Controller was disconnected
1286}
1287
1288
1289void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
1290{
1291 if ( device )
1292 {
1293 LOGV( "hid_close id=%d", device->m_nId );
1294 hid_mutex_guard r( &g_DevicesRefCountMutex );
1295 LOGD("Decrementing device %d (%p), refCount = %d\n", device->m_nId, device, device->m_nDeviceRefCount - 1);
1296 if ( --device->m_nDeviceRefCount == 0 )
1297 {
1298 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1299 if ( pDevice )
1300 {
1301 pDevice->Close( true );
1302 }
1303 else
1304 {
1305 delete device;
1306 }
1307 LOGD("Deleted device %p\n", device);
1308 }
1309 }
1310}
1311
1312int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
1313{
1314 if ( device )
1315 {
1316 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1317 if ( pDevice )
1318 {
1319 wcsncpy( string, pDevice->GetDeviceInfo()->manufacturer_string, maxlen );
1320 return 0;
1321 }
1322 }
1323 return -1;
1324}
1325
1326int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
1327{
1328 if ( device )
1329 {
1330 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1331 if ( pDevice )
1332 {
1333 wcsncpy( string, pDevice->GetDeviceInfo()->product_string, maxlen );
1334 return 0;
1335 }
1336 }
1337 return -1;
1338}
1339
1340int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
1341{
1342 if ( device )
1343 {
1344 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1345 if ( pDevice )
1346 {
1347 wcsncpy( string, pDevice->GetDeviceInfo()->serial_number, maxlen );
1348 return 0;
1349 }
1350 }
1351 return -1;
1352}
1353
1354int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen)
1355{
1356 return -1;
1357}
1358
1359struct hid_device_info *hid_get_device_info(hid_device *device)
1360{
1361 if ( device )
1362 {
1363 hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
1364 if ( pDevice )
1365 {
1366 return pDevice->GetDeviceInfo();
1367 }
1368 }
1369 return NULL;
1370}
1371
1372int hid_get_report_descriptor(hid_device *device, unsigned char *buf, size_t buf_size)
1373{
1374 // Not implemented
1375 return -1;
1376}
1377
1378HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device)
1379{
1380 return NULL;
1381}
1382
1383int hid_exit(void)
1384{
1385 return 0;
1386}
1387
1388}
1389
1390#else
1391
1392extern "C"
1393JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
1394
1395extern "C"
1396JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
1397
1398extern "C"
1399JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol, bool bBluetooth );
1400
1401extern "C"
1402JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);
1403
1404extern "C"
1405JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);
1406
1407extern "C"
1408JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);
1409
1410extern "C"
1411JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
1412
1413extern "C"
1414JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReportResponse)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
1415
1416
1417extern "C"
1418JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
1419{
1420 LOGV("Stub HIDDeviceRegisterCallback()");
1421}
1422
1423extern "C"
1424JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
1425{
1426 LOGV("Stub HIDDeviceReleaseCallback()");
1427}
1428
1429extern "C"
1430JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol, bool bBluetooth )
1431{
1432 LOGV("Stub HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface);
1433}
1434
1435extern "C"
1436JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID)
1437{
1438 LOGV("Stub HIDDeviceOpenPending() id=%d\n", nDeviceID);
1439}
1440
1441extern "C"
1442JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened)
1443{
1444 LOGV("Stub HIDDeviceOpenResult() id=%d, result=%s\n", nDeviceID, bOpened ? "true" : "false");
1445}
1446
1447extern "C"
1448JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID)
1449{
1450 LOGV("Stub HIDDeviceDisconnected() id=%d\n", nDeviceID);
1451}
1452
1453extern "C"
1454JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
1455{
1456 LOGV("Stub HIDDeviceInput() id=%d len=%u\n", nDeviceID, nBufSize);
1457}
1458
1459extern "C"
1460JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReportResponse)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
1461{
1462 LOGV("Stub HIDDeviceReportResponse() id=%d len=%u\n", nDeviceID, nBufSize);
1463}
1464
1465#endif /* SDL_HIDAPI_DISABLED */
1466
1467extern "C"
1468JNINativeMethod HIDDeviceManager_tab[8] = {
1469 { "HIDDeviceRegisterCallback", "()V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback) },
1470 { "HIDDeviceReleaseCallback", "()V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback) },
1471 { "HIDDeviceConnected", "(ILjava/lang/String;IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;IIIIZ)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected) },
1472 { "HIDDeviceOpenPending", "(I)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending) },
1473 { "HIDDeviceOpenResult", "(IZ)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult) },
1474 { "HIDDeviceDisconnected", "(I)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected) },
1475 { "HIDDeviceInputReport", "(I[B)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport) },
1476 { "HIDDeviceReportResponse", "(I[B)V", (void*)HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReportResponse) }
1477};
diff --git a/contrib/SDL-3.2.8/src/hidapi/android/hid.h b/contrib/SDL-3.2.8/src/hidapi/android/hid.h
new file mode 100644
index 0000000..5e6253b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/android/hid.h
@@ -0,0 +1,39 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 2022 Valve Corporation
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22// Purpose: Exporting table containing HIDDeviceManager native methods
23
24#ifndef SDL_android_hid_h_
25#define SDL_android_hid_h_
26
27#include <jni.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33extern JNINativeMethod HIDDeviceManager_tab[8];
34
35#ifdef __cplusplus
36}
37#endif
38
39#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/bootstrap b/contrib/SDL-3.2.8/src/hidapi/bootstrap
new file mode 100755
index 0000000..81e9b74
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/bootstrap
@@ -0,0 +1,2 @@
1#!/bin/sh -x
2autoreconf --install --verbose --force
diff --git a/contrib/SDL-3.2.8/src/hidapi/configure.ac b/contrib/SDL-3.2.8/src/hidapi/configure.ac
new file mode 100644
index 0000000..1b20510
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/configure.ac
@@ -0,0 +1,256 @@
1AC_PREREQ(2.63)
2
3AC_INIT([hidapi],[m4_normalize(m4_builtin([include], VERSION))],[https://github.com/libusb/hidapi/issues])
4
5echo "This build script for HIDAPI is deprecated."
6echo "Consider using CMake instead."
7
8# Library soname version
9# Follow the following rules (particularly the ones in the second link):
10# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
11# http://sourceware.org/autobook/autobook/autobook_91.html
12lt_current="0"
13lt_revision="0"
14lt_age="0"
15LTLDFLAGS="-version-info ${lt_current}:${lt_revision}:${lt_age}"
16
17AC_CONFIG_MACRO_DIR([m4])
18AM_INIT_AUTOMAKE([foreign -Wall -Werror])
19
20m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
21LT_INIT
22
23AC_PROG_CC
24AC_PROG_CXX
25AC_PROG_OBJC
26PKG_PROG_PKG_CONFIG
27
28
29m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
30
31hidapi_lib_error() {
32 echo ""
33 echo " Library $1 was not found on this system."
34 echo " Please install it and re-run ./configure"
35 echo ""
36 exit 1
37}
38
39hidapi_prog_error() {
40 echo ""
41 echo " Program $1 was not found on this system."
42 echo " This program is part of $2."
43 echo " Please install it and re-run ./configure"
44 echo ""
45 exit 1
46}
47
48AC_MSG_CHECKING([operating system])
49AC_MSG_RESULT($host)
50case $host in
51*-linux*)
52 AC_MSG_RESULT([ (Linux back-end)])
53 AC_DEFINE(OS_LINUX, 1, [Linux implementations])
54 AC_SUBST(OS_LINUX)
55 backend="linux"
56 os="linux"
57 threads="pthreads"
58
59 # HIDAPI/hidraw libs
60 PKG_CHECK_MODULES([libudev], [libudev], true, [hidapi_lib_error libudev])
61 LIBS_HIDRAW_PR="${LIBS_HIDRAW_PR} $libudev_LIBS"
62 CFLAGS_HIDRAW="${CFLAGS_HIDRAW} $libudev_CFLAGS"
63
64 # HIDAPI/libusb libs
65 AC_CHECK_LIB([rt], [clock_gettime], [LIBS_LIBUSB_PRIVATE="${LIBS_LIBUSB_PRIVATE} -lrt"], [hidapi_lib_error librt])
66 PKG_CHECK_MODULES([libusb], [libusb-1.0 >= 1.0.9], true, [hidapi_lib_error libusb-1.0])
67 LIBS_LIBUSB_PRIVATE="${LIBS_LIBUSB_PRIVATE} $libusb_LIBS"
68 CFLAGS_LIBUSB="${CFLAGS_LIBUSB} $libusb_CFLAGS"
69 ;;
70*-darwin*)
71 AC_MSG_RESULT([ (Mac OS X back-end)])
72 AC_DEFINE(OS_DARWIN, 1, [Mac implementation])
73 AC_SUBST(OS_DARWIN)
74 backend="mac"
75 os="darwin"
76 threads="pthreads"
77 LIBS="${LIBS} -framework IOKit -framework CoreFoundation"
78 ;;
79*-freebsd*)
80 AC_MSG_RESULT([ (FreeBSD back-end)])
81 AC_DEFINE(OS_FREEBSD, 1, [FreeBSD implementation])
82 AC_SUBST(OS_FREEBSD)
83 backend="libusb"
84 os="freebsd"
85 threads="pthreads"
86
87 CFLAGS="$CFLAGS -I/usr/local/include"
88 LDFLAGS="$LDFLAGS -L/usr/local/lib"
89 LIBS="${LIBS}"
90 PKG_CHECK_MODULES([libusb], [libusb-1.0 >= 1.0.9], true, [hidapi_lib_error libusb-1.0])
91 LIBS_LIBUSB_PRIVATE="${LIBS_LIBUSB_PRIVATE} $libusb_LIBS"
92 CFLAGS_LIBUSB="${CFLAGS_LIBUSB} $libusb_CFLAGS"
93 AC_CHECK_LIB([iconv], [iconv_open], [LIBS_LIBUSB_PRIVATE="${LIBS_LIBUSB_PRIVATE} -liconv"], [hidapi_lib_error libiconv])
94 ;;
95*-kfreebsd*)
96 AC_MSG_RESULT([ (kFreeBSD back-end)])
97 AC_DEFINE(OS_KFREEBSD, 1, [kFreeBSD implementation])
98 AC_SUBST(OS_KFREEBSD)
99 backend="libusb"
100 os="kfreebsd"
101 threads="pthreads"
102
103 PKG_CHECK_MODULES([libusb], [libusb-1.0 >= 1.0.9], true, [hidapi_lib_error libusb-1.0])
104 LIBS_LIBUSB_PRIVATE="${LIBS_LIBUSB_PRIVATE} $libusb_LIBS"
105 CFLAGS_LIBUSB="${CFLAGS_LIBUSB} $libusb_CFLAGS"
106 ;;
107*-*-haiku)
108 AC_MSG_RESULT([ (Haiku back-end)])
109 AC_DEFINE(OS_HAIKU, 1, [Haiku implementation])
110 AC_SUBST(OS_HAIKU)
111 backend="libusb"
112 os="haiku"
113 threads="pthreads"
114
115 PKG_CHECK_MODULES([libusb], [libusb-1.0 >= 1.0.9], true, [hidapi_lib_error libusb-1.0])
116 LIBS_LIBUSB_PRIVATE="${LIBS_LIBUSB_PRIVATE} $libusb_LIBS"
117 CFLAGS_LIBUSB="${CFLAGS_LIBUSB} $libusb_CFLAGS"
118 AC_CHECK_LIB([iconv], [libiconv_open], [LIBS_LIBUSB_PRIVATE="${LIBS_LIBUSB_PRIVATE} -liconv"], [hidapi_lib_error libiconv])
119 ;;
120*-mingw*)
121 AC_MSG_RESULT([ (Windows back-end, using MinGW)])
122 backend="windows"
123 os="windows"
124 threads="windows"
125 win_implementation="mingw"
126 LDFLAGS="${LDFLAGS} -static-libgcc"
127 ;;
128*-msys*)
129 AC_MSG_RESULT([ (Windows back-end, using MSYS2)])
130 backend="windows"
131 os="windows"
132 threads="windows"
133 win_implementation="mingw"
134 LDFLAGS="${LDFLAGS} -static-libgcc"
135 ;;
136*-cygwin*)
137 AC_MSG_RESULT([ (Windows back-end, using Cygwin)])
138 backend="windows"
139 os="windows"
140 threads="windows"
141 win_implementation="cygwin"
142 ;;
143*)
144 AC_MSG_ERROR([HIDAPI is not supported on your operating system yet])
145esac
146
147LIBS_HIDRAW="${LIBS} ${LIBS_HIDRAW_PR}"
148LIBS_LIBUSB="${LIBS} ${LIBS_LIBUSB_PRIVATE}"
149AC_SUBST([LIBS_HIDRAW])
150AC_SUBST([LIBS_LIBUSB])
151AC_SUBST([CFLAGS_LIBUSB])
152AC_SUBST([CFLAGS_HIDRAW])
153
154if test "x$os" = xwindows; then
155 AC_DEFINE(OS_WINDOWS, 1, [Windows implementations])
156 AC_SUBST(OS_WINDOWS)
157 LDFLAGS="${LDFLAGS} -no-undefined"
158 LIBS="${LIBS}"
159fi
160
161if test "x$threads" = xpthreads; then
162 AX_PTHREAD([found_pthreads=yes], [found_pthreads=no])
163
164 if test "x$found_pthreads" = xyes; then
165 if test "x$os" = xlinux; then
166 # Only use pthreads for libusb implementation on Linux.
167 LIBS_LIBUSB="$PTHREAD_LIBS $LIBS_LIBUSB"
168 CFLAGS_LIBUSB="$CFLAGS_LIBUSB $PTHREAD_CFLAGS"
169 # There's no separate CC on Linux for threading,
170 # so it's ok that both implementations use $PTHREAD_CC
171 CC="$PTHREAD_CC"
172 else
173 LIBS="$PTHREAD_LIBS $LIBS"
174 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
175 CC="$PTHREAD_CC"
176 fi
177 fi
178fi
179
180# Test GUI
181AC_ARG_ENABLE([testgui],
182 [AS_HELP_STRING([--enable-testgui],
183 [enable building of test GUI (default n)])],
184 [testgui_enabled=$enableval],
185 [testgui_enabled='no'])
186AM_CONDITIONAL([BUILD_TESTGUI], [test "x$testgui_enabled" != "xno"])
187
188# Configure the MacOS TestGUI app bundle
189rm -Rf testgui/TestGUI.app
190mkdir -p testgui/TestGUI.app
191cp -R ${srcdir}/testgui/TestGUI.app.in/* testgui/TestGUI.app
192chmod -R u+w testgui/TestGUI.app
193mkdir testgui/TestGUI.app/Contents/MacOS/
194
195if test "x$testgui_enabled" != "xno"; then
196 if test "x$os" = xdarwin; then
197 # On Mac OS, do not use pkg-config.
198 AC_CHECK_PROG([foxconfig], [fox-config], [fox-config], false)
199 if test "x$foxconfig" = "xfalse"; then
200 hidapi_prog_error fox-config "FOX Toolkit"
201 fi
202 LIBS_TESTGUI="${LIBS_TESTGUI} `$foxconfig --libs`"
203 LIBS_TESTGUI="${LIBS_TESTGUI} -framework Cocoa -L/usr/X11R6/lib"
204 CFLAGS_TESTGUI="${CFLAGS_TESTGUI} `$foxconfig --cflags`"
205 OBJCFLAGS="${OBJCFLAGS} -x objective-c++"
206 elif test "x$os" = xwindows; then
207 # On Windows, just set the paths for Fox toolkit
208 if test "x$win_implementation" = xmingw; then
209 CFLAGS_TESTGUI="-I\$(srcdir)/../../hidapi-externals/fox/include -g -c"
210 LIBS_TESTGUI=" -mwindows \$(srcdir)/../../hidapi-externals/fox/lib/libFOX-1.6.a -lgdi32 -Wl,--enable-auto-import -static-libgcc -static-libstdc++ -lkernel32"
211 else
212 # Cygwin
213 CFLAGS_TESTGUI="-DWIN32 -I\$(srcdir)/../../hidapi-externals/fox/include -g -c"
214 LIBS_TESTGUI="\$(srcdir)/../../hidapi-externals/fox/lib/libFOX-cygwin-1.6.a -lgdi32 -Wl,--enable-auto-import -static-libgcc -static-libstdc++ -lkernel32"
215 fi
216 else
217 # On Linux and FreeBSD platforms, use pkg-config to find fox.
218 PKG_CHECK_MODULES([fox], [fox17], [], [PKG_CHECK_MODULES([fox], [fox])])
219 LIBS_TESTGUI="${LIBS_TESTGUI} $fox_LIBS"
220 if test "x$os" = xfreebsd; then
221 LIBS_TESTGUI="${LIBS_TESTGUI} -L/usr/local/lib"
222 fi
223 CFLAGS_TESTGUI="${CFLAGS_TESTGUI} $fox_CFLAGS"
224 fi
225fi
226AC_SUBST([LIBS_TESTGUI])
227AC_SUBST([CFLAGS_TESTGUI])
228AC_SUBST([backend])
229
230# OS info for Automake
231AM_CONDITIONAL(OS_LINUX, test "x$os" = xlinux)
232AM_CONDITIONAL(OS_DARWIN, test "x$os" = xdarwin)
233AM_CONDITIONAL(OS_FREEBSD, test "x$os" = xfreebsd)
234AM_CONDITIONAL(OS_KFREEBSD, test "x$os" = xkfreebsd)
235AM_CONDITIONAL(OS_HAIKU, test "x$os" = xhaiku)
236AM_CONDITIONAL(OS_WINDOWS, test "x$os" = xwindows)
237
238AC_CONFIG_HEADERS([config.h])
239
240if test "x$os" = "xlinux"; then
241 AC_CONFIG_FILES([pc/hidapi-hidraw.pc])
242 AC_CONFIG_FILES([pc/hidapi-libusb.pc])
243else
244 AC_CONFIG_FILES([pc/hidapi.pc])
245fi
246
247AC_SUBST(LTLDFLAGS)
248
249AC_CONFIG_FILES([Makefile \
250 hidtest/Makefile \
251 libusb/Makefile \
252 linux/Makefile \
253 mac/Makefile \
254 testgui/Makefile \
255 windows/Makefile])
256AC_OUTPUT
diff --git a/contrib/SDL-3.2.8/src/hidapi/dist/hidapi.podspec b/contrib/SDL-3.2.8/src/hidapi/dist/hidapi.podspec
new file mode 100644
index 0000000..8588514
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/dist/hidapi.podspec
@@ -0,0 +1,31 @@
1Pod::Spec.new do |spec|
2
3 spec.name = "hidapi"
4 spec.version = File.read('../VERSION')
5 spec.summary = "A Simple library for communicating with USB and Bluetooth HID devices on Linux, Mac and Windows."
6
7 spec.description = <<-DESC
8 HIDAPI is a multi-platform library which allows an application to interface with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and macOS. HIDAPI can be either built as a shared library (.so, .dll or .dylib) or can be embedded directly into a target application by adding a single source file (per platform) and a single header.
9 DESC
10
11 spec.homepage = "https://github.com/libusb/hidapi"
12
13 spec.license = { :type=> "GNU GPLv3 or BSD or HIDAPI original", :file => "LICENSE.txt" }
14
15 spec.authors = { "Alan Ott" => "alan@signal11.us",
16 "Ludovic Rousseau" => "rousseau@debian.org",
17 "libusb/hidapi Team" => "https://github.com/libusb/hidapi/blob/master/AUTHORS.txt",
18 }
19
20 spec.platform = :osx
21 spec.osx.deployment_target = "10.7"
22
23 spec.source = { :git => "https://github.com/libusb/hidapi.git", :tag => "hidapi-#{spec.version}" }
24
25 spec.source_files = "mac/hid.c", "hidapi/hidapi.h", "mac/hidapi_darwin.h"
26
27 spec.public_header_files = "hidapi/hidapi.h", "mac/hidapi_darwin.h"
28
29 spec.frameworks = "IOKit", "CoreFoundation"
30
31end
diff --git a/contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-drop-down.png b/contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-drop-down.png
new file mode 100644
index 0000000..548abe8
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-drop-down.png
Binary files differ
diff --git a/contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-highlights.png b/contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-highlights.png
new file mode 100644
index 0000000..228838f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/documentation/cmake-gui-highlights.png
Binary files differ
diff --git a/contrib/SDL-3.2.8/src/hidapi/doxygen/Doxyfile b/contrib/SDL-3.2.8/src/hidapi/doxygen/Doxyfile
new file mode 100644
index 0000000..b0bc233
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/doxygen/Doxyfile
@@ -0,0 +1,2724 @@
1# Doxyfile 1.9.6
2
3# This file describes the settings to be used by the documentation system
4# doxygen (www.doxygen.org) for a project.
5#
6# All text after a double hash (##) is considered a comment and is placed in
7# front of the TAG it is preceding.
8#
9# All text after a single hash (#) is considered a comment and will be ignored.
10# The format is:
11# TAG = value [value, ...]
12# For lists, items can also be appended using:
13# TAG += value [value, ...]
14# Values that contain spaces should be placed between quotes (\" \").
15#
16# Note:
17#
18# Use doxygen to compare the used configuration file with the template
19# configuration file:
20# doxygen -x [configFile]
21# Use doxygen to compare the used configuration file with the template
22# configuration file without replacing the environment variables or CMake type
23# replacement variables:
24# doxygen -x_noenv [configFile]
25
26#---------------------------------------------------------------------------
27# Project related configuration options
28#---------------------------------------------------------------------------
29
30# This tag specifies the encoding used for all characters in the configuration
31# file that follow. The default is UTF-8 which is also the encoding used for all
32# text before the first occurrence of this tag. Doxygen uses libiconv (or the
33# iconv built into libc) for the transcoding. See
34# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
35# The default value is: UTF-8.
36
37DOXYFILE_ENCODING = UTF-8
38
39# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
40# double-quotes, unless you are using Doxywizard) that should identify the
41# project for which the documentation is generated. This name is used in the
42# title of most generated pages and in a few other places.
43# The default value is: My Project.
44
45PROJECT_NAME = hidapi
46
47# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
48# could be handy for archiving the generated documentation or if some version
49# control system is used.
50
51PROJECT_NUMBER =
52
53# Using the PROJECT_BRIEF tag one can provide an optional one line description
54# for a project that appears at the top of each page and should give viewer a
55# quick idea about the purpose of the project. Keep the description short.
56
57PROJECT_BRIEF =
58
59# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
60# in the documentation. The maximum height of the logo should not exceed 55
61# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
62# the logo to the output directory.
63
64PROJECT_LOGO =
65
66# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
67# into which the generated documentation will be written. If a relative path is
68# entered, it will be relative to the location where doxygen was started. If
69# left blank the current directory will be used.
70
71OUTPUT_DIRECTORY =
72
73# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
74# sub-directories (in 2 levels) under the output directory of each output format
75# and will distribute the generated files over these directories. Enabling this
76# option can be useful when feeding doxygen a huge amount of source files, where
77# putting all generated files in the same directory would otherwise causes
78# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to
79# control the number of sub-directories.
80# The default value is: NO.
81
82CREATE_SUBDIRS = NO
83
84# Controls the number of sub-directories that will be created when
85# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every
86# level increment doubles the number of directories, resulting in 4096
87# directories at level 8 which is the default and also the maximum value. The
88# sub-directories are organized in 2 levels, the first level always has a fixed
89# number of 16 directories.
90# Minimum value: 0, maximum value: 8, default value: 8.
91# This tag requires that the tag CREATE_SUBDIRS is set to YES.
92
93CREATE_SUBDIRS_LEVEL = 8
94
95# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
96# characters to appear in the names of generated files. If set to NO, non-ASCII
97# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
98# U+3044.
99# The default value is: NO.
100
101ALLOW_UNICODE_NAMES = NO
102
103# The OUTPUT_LANGUAGE tag is used to specify the language in which all
104# documentation generated by doxygen is written. Doxygen will use this
105# information to generate all constant output in the proper language.
106# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian,
107# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English
108# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek,
109# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with
110# English messages), Korean, Korean-en (Korean with English messages), Latvian,
111# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese,
112# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish,
113# Swedish, Turkish, Ukrainian and Vietnamese.
114# The default value is: English.
115
116OUTPUT_LANGUAGE = English
117
118# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
119# descriptions after the members that are listed in the file and class
120# documentation (similar to Javadoc). Set to NO to disable this.
121# The default value is: YES.
122
123BRIEF_MEMBER_DESC = YES
124
125# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
126# description of a member or function before the detailed description
127#
128# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
129# brief descriptions will be completely suppressed.
130# The default value is: YES.
131
132REPEAT_BRIEF = YES
133
134# This tag implements a quasi-intelligent brief description abbreviator that is
135# used to form the text in various listings. Each string in this list, if found
136# as the leading text of the brief description, will be stripped from the text
137# and the result, after processing the whole list, is used as the annotated
138# text. Otherwise, the brief description is used as-is. If left blank, the
139# following values are used ($name is automatically replaced with the name of
140# the entity):The $name class, The $name widget, The $name file, is, provides,
141# specifies, contains, represents, a, an and the.
142
143ABBREVIATE_BRIEF =
144
145# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
146# doxygen will generate a detailed section even if there is only a brief
147# description.
148# The default value is: NO.
149
150ALWAYS_DETAILED_SEC = NO
151
152# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
153# inherited members of a class in the documentation of that class as if those
154# members were ordinary class members. Constructors, destructors and assignment
155# operators of the base classes will not be shown.
156# The default value is: NO.
157
158INLINE_INHERITED_MEMB = NO
159
160# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
161# before files name in the file list and in the header files. If set to NO the
162# shortest path that makes the file name unique will be used
163# The default value is: YES.
164
165FULL_PATH_NAMES = YES
166
167# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
168# Stripping is only done if one of the specified strings matches the left-hand
169# part of the path. The tag can be used to show relative paths in the file list.
170# If left blank the directory from which doxygen is run is used as the path to
171# strip.
172#
173# Note that you can specify absolute paths here, but also relative paths, which
174# will be relative from the directory where doxygen is started.
175# This tag requires that the tag FULL_PATH_NAMES is set to YES.
176
177STRIP_FROM_PATH = ../
178
179# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
180# path mentioned in the documentation of a class, which tells the reader which
181# header file to include in order to use a class. If left blank only the name of
182# the header file containing the class definition is used. Otherwise one should
183# specify the list of include paths that are normally passed to the compiler
184# using the -I flag.
185
186STRIP_FROM_INC_PATH =
187
188# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
189# less readable) file names. This can be useful is your file systems doesn't
190# support long names like on DOS, Mac, or CD-ROM.
191# The default value is: NO.
192
193SHORT_NAMES = NO
194
195# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
196# first line (until the first dot) of a Javadoc-style comment as the brief
197# description. If set to NO, the Javadoc-style will behave just like regular Qt-
198# style comments (thus requiring an explicit @brief command for a brief
199# description.)
200# The default value is: NO.
201
202JAVADOC_AUTOBRIEF = NO
203
204# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
205# such as
206# /***************
207# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
208# Javadoc-style will behave just like regular comments and it will not be
209# interpreted by doxygen.
210# The default value is: NO.
211
212JAVADOC_BANNER = NO
213
214# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
215# line (until the first dot) of a Qt-style comment as the brief description. If
216# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
217# requiring an explicit command for a brief description.)
218# The default value is: NO.
219
220QT_AUTOBRIEF = NO
221
222# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
223# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
224# a brief description. This used to be the default behavior. The new default is
225# to treat a multi-line C++ comment block as a detailed description. Set this
226# tag to YES if you prefer the old behavior instead.
227#
228# Note that setting this tag to YES also means that rational rose comments are
229# not recognized any more.
230# The default value is: NO.
231
232MULTILINE_CPP_IS_BRIEF = NO
233
234# By default Python docstrings are displayed as preformatted text and doxygen's
235# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
236# doxygen's special commands can be used and the contents of the docstring
237# documentation blocks is shown as doxygen documentation.
238# The default value is: YES.
239
240PYTHON_DOCSTRING = YES
241
242# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
243# documentation from any documented member that it re-implements.
244# The default value is: YES.
245
246INHERIT_DOCS = YES
247
248# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
249# page for each member. If set to NO, the documentation of a member will be part
250# of the file/class/namespace that contains it.
251# The default value is: NO.
252
253SEPARATE_MEMBER_PAGES = NO
254
255# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
256# uses this value to replace tabs by spaces in code fragments.
257# Minimum value: 1, maximum value: 16, default value: 4.
258
259TAB_SIZE = 8
260
261# This tag can be used to specify a number of aliases that act as commands in
262# the documentation. An alias has the form:
263# name=value
264# For example adding
265# "sideeffect=@par Side Effects:^^"
266# will allow you to put the command \sideeffect (or @sideeffect) in the
267# documentation, which will result in a user-defined paragraph with heading
268# "Side Effects:". Note that you cannot put \n's in the value part of an alias
269# to insert newlines (in the resulting output). You can put ^^ in the value part
270# of an alias to insert a newline as if a physical newline was in the original
271# file. When you need a literal { or } or , in the value part of an alias you
272# have to escape them by means of a backslash (\), this can lead to conflicts
273# with the commands \{ and \} for these it is advised to use the version @{ and
274# @} or use a double escape (\\{ and \\})
275
276ALIASES =
277
278# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
279# only. Doxygen will then generate output that is more tailored for C. For
280# instance, some of the names that are used will be different. The list of all
281# members will be omitted, etc.
282# The default value is: NO.
283
284OPTIMIZE_OUTPUT_FOR_C = YES
285
286# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
287# Python sources only. Doxygen will then generate output that is more tailored
288# for that language. For instance, namespaces will be presented as packages,
289# qualified scopes will look different, etc.
290# The default value is: NO.
291
292OPTIMIZE_OUTPUT_JAVA = NO
293
294# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
295# sources. Doxygen will then generate output that is tailored for Fortran.
296# The default value is: NO.
297
298OPTIMIZE_FOR_FORTRAN = NO
299
300# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
301# sources. Doxygen will then generate output that is tailored for VHDL.
302# The default value is: NO.
303
304OPTIMIZE_OUTPUT_VHDL = NO
305
306# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
307# sources only. Doxygen will then generate output that is more tailored for that
308# language. For instance, namespaces will be presented as modules, types will be
309# separated into more groups, etc.
310# The default value is: NO.
311
312OPTIMIZE_OUTPUT_SLICE = NO
313
314# Doxygen selects the parser to use depending on the extension of the files it
315# parses. With this tag you can assign which parser to use for a given
316# extension. Doxygen has a built-in mapping, but you can override or extend it
317# using this tag. The format is ext=language, where ext is a file extension, and
318# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
319# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice,
320# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
321# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
322# tries to guess whether the code is fixed or free formatted code, this is the
323# default for Fortran type files). For instance to make doxygen treat .inc files
324# as Fortran files (default is PHP), and .f files as C (default is Fortran),
325# use: inc=Fortran f=C.
326#
327# Note: For files without extension you can use no_extension as a placeholder.
328#
329# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
330# the files are not read by doxygen. When specifying no_extension you should add
331# * to the FILE_PATTERNS.
332#
333# Note see also the list of default file extension mappings.
334
335EXTENSION_MAPPING =
336
337# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
338# according to the Markdown format, which allows for more readable
339# documentation. See https://daringfireball.net/projects/markdown/ for details.
340# The output of markdown processing is further processed by doxygen, so you can
341# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
342# case of backward compatibilities issues.
343# The default value is: YES.
344
345MARKDOWN_SUPPORT = NO
346
347# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
348# to that level are automatically included in the table of contents, even if
349# they do not have an id attribute.
350# Note: This feature currently applies only to Markdown headings.
351# Minimum value: 0, maximum value: 99, default value: 5.
352# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
353
354TOC_INCLUDE_HEADINGS = 5
355
356# When enabled doxygen tries to link words that correspond to documented
357# classes, or namespaces to their corresponding documentation. Such a link can
358# be prevented in individual cases by putting a % sign in front of the word or
359# globally by setting AUTOLINK_SUPPORT to NO.
360# The default value is: YES.
361
362AUTOLINK_SUPPORT = YES
363
364# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
365# to include (a tag file for) the STL sources as input, then you should set this
366# tag to YES in order to let doxygen match functions declarations and
367# definitions whose arguments contain STL classes (e.g. func(std::string);
368# versus func(std::string) {}). This also make the inheritance and collaboration
369# diagrams that involve STL classes more complete and accurate.
370# The default value is: NO.
371
372BUILTIN_STL_SUPPORT = NO
373
374# If you use Microsoft's C++/CLI language, you should set this option to YES to
375# enable parsing support.
376# The default value is: NO.
377
378CPP_CLI_SUPPORT = NO
379
380# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
381# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
382# will parse them like normal C++ but will assume all classes use public instead
383# of private inheritance when no explicit protection keyword is present.
384# The default value is: NO.
385
386SIP_SUPPORT = NO
387
388# For Microsoft's IDL there are propget and propput attributes to indicate
389# getter and setter methods for a property. Setting this option to YES will make
390# doxygen to replace the get and set methods by a property in the documentation.
391# This will only work if the methods are indeed getting or setting a simple
392# type. If this is not the case, or you want to show the methods anyway, you
393# should set this option to NO.
394# The default value is: YES.
395
396IDL_PROPERTY_SUPPORT = YES
397
398# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
399# tag is set to YES then doxygen will reuse the documentation of the first
400# member in the group (if any) for the other members of the group. By default
401# all members of a group must be documented explicitly.
402# The default value is: NO.
403
404DISTRIBUTE_GROUP_DOC = NO
405
406# If one adds a struct or class to a group and this option is enabled, then also
407# any nested class or struct is added to the same group. By default this option
408# is disabled and one has to add nested compounds explicitly via \ingroup.
409# The default value is: NO.
410
411GROUP_NESTED_COMPOUNDS = NO
412
413# Set the SUBGROUPING tag to YES to allow class member groups of the same type
414# (for instance a group of public functions) to be put as a subgroup of that
415# type (e.g. under the Public Functions section). Set it to NO to prevent
416# subgrouping. Alternatively, this can be done per class using the
417# \nosubgrouping command.
418# The default value is: YES.
419
420SUBGROUPING = YES
421
422# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
423# are shown inside the group in which they are included (e.g. using \ingroup)
424# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
425# and RTF).
426#
427# Note that this feature does not work in combination with
428# SEPARATE_MEMBER_PAGES.
429# The default value is: NO.
430
431INLINE_GROUPED_CLASSES = NO
432
433# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
434# with only public data fields or simple typedef fields will be shown inline in
435# the documentation of the scope in which they are defined (i.e. file,
436# namespace, or group documentation), provided this scope is documented. If set
437# to NO, structs, classes, and unions are shown on a separate page (for HTML and
438# Man pages) or section (for LaTeX and RTF).
439# The default value is: NO.
440
441INLINE_SIMPLE_STRUCTS = NO
442
443# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
444# enum is documented as struct, union, or enum with the name of the typedef. So
445# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
446# with name TypeT. When disabled the typedef will appear as a member of a file,
447# namespace, or class. And the struct will be named TypeS. This can typically be
448# useful for C code in case the coding convention dictates that all compound
449# types are typedef'ed and only the typedef is referenced, never the tag name.
450# The default value is: NO.
451
452TYPEDEF_HIDES_STRUCT = NO
453
454# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
455# cache is used to resolve symbols given their name and scope. Since this can be
456# an expensive process and often the same symbol appears multiple times in the
457# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
458# doxygen will become slower. If the cache is too large, memory is wasted. The
459# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
460# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
461# symbols. At the end of a run doxygen will report the cache usage and suggest
462# the optimal cache size from a speed point of view.
463# Minimum value: 0, maximum value: 9, default value: 0.
464
465LOOKUP_CACHE_SIZE = 0
466
467# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use
468# during processing. When set to 0 doxygen will based this on the number of
469# cores available in the system. You can set it explicitly to a value larger
470# than 0 to get more control over the balance between CPU load and processing
471# speed. At this moment only the input processing can be done using multiple
472# threads. Since this is still an experimental feature the default is set to 1,
473# which effectively disables parallel processing. Please report any issues you
474# encounter. Generating dot graphs in parallel is controlled by the
475# DOT_NUM_THREADS setting.
476# Minimum value: 0, maximum value: 32, default value: 1.
477
478NUM_PROC_THREADS = 1
479
480#---------------------------------------------------------------------------
481# Build related configuration options
482#---------------------------------------------------------------------------
483
484# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
485# documentation are documented, even if no documentation was available. Private
486# class members and static file members will be hidden unless the
487# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
488# Note: This will also disable the warnings about undocumented members that are
489# normally produced when WARNINGS is set to YES.
490# The default value is: NO.
491
492EXTRACT_ALL = NO
493
494# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
495# be included in the documentation.
496# The default value is: NO.
497
498EXTRACT_PRIVATE = NO
499
500# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
501# methods of a class will be included in the documentation.
502# The default value is: NO.
503
504EXTRACT_PRIV_VIRTUAL = NO
505
506# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
507# scope will be included in the documentation.
508# The default value is: NO.
509
510EXTRACT_PACKAGE = NO
511
512# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
513# included in the documentation.
514# The default value is: NO.
515
516EXTRACT_STATIC = NO
517
518# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
519# locally in source files will be included in the documentation. If set to NO,
520# only classes defined in header files are included. Does not have any effect
521# for Java sources.
522# The default value is: YES.
523
524EXTRACT_LOCAL_CLASSES = YES
525
526# This flag is only useful for Objective-C code. If set to YES, local methods,
527# which are defined in the implementation section but not in the interface are
528# included in the documentation. If set to NO, only methods in the interface are
529# included.
530# The default value is: NO.
531
532EXTRACT_LOCAL_METHODS = NO
533
534# If this flag is set to YES, the members of anonymous namespaces will be
535# extracted and appear in the documentation as a namespace called
536# 'anonymous_namespace{file}', where file will be replaced with the base name of
537# the file that contains the anonymous namespace. By default anonymous namespace
538# are hidden.
539# The default value is: NO.
540
541EXTRACT_ANON_NSPACES = NO
542
543# If this flag is set to YES, the name of an unnamed parameter in a declaration
544# will be determined by the corresponding definition. By default unnamed
545# parameters remain unnamed in the output.
546# The default value is: YES.
547
548RESOLVE_UNNAMED_PARAMS = YES
549
550# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
551# undocumented members inside documented classes or files. If set to NO these
552# members will be included in the various overviews, but no documentation
553# section is generated. This option has no effect if EXTRACT_ALL is enabled.
554# The default value is: NO.
555
556HIDE_UNDOC_MEMBERS = NO
557
558# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
559# undocumented classes that are normally visible in the class hierarchy. If set
560# to NO, these classes will be included in the various overviews. This option
561# will also hide undocumented C++ concepts if enabled. This option has no effect
562# if EXTRACT_ALL is enabled.
563# The default value is: NO.
564
565HIDE_UNDOC_CLASSES = NO
566
567# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
568# declarations. If set to NO, these declarations will be included in the
569# documentation.
570# The default value is: NO.
571
572HIDE_FRIEND_COMPOUNDS = NO
573
574# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
575# documentation blocks found inside the body of a function. If set to NO, these
576# blocks will be appended to the function's detailed documentation block.
577# The default value is: NO.
578
579HIDE_IN_BODY_DOCS = NO
580
581# The INTERNAL_DOCS tag determines if documentation that is typed after a
582# \internal command is included. If the tag is set to NO then the documentation
583# will be excluded. Set it to YES to include the internal documentation.
584# The default value is: NO.
585
586INTERNAL_DOCS = NO
587
588# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
589# able to match the capabilities of the underlying filesystem. In case the
590# filesystem is case sensitive (i.e. it supports files in the same directory
591# whose names only differ in casing), the option must be set to YES to properly
592# deal with such files in case they appear in the input. For filesystems that
593# are not case sensitive the option should be set to NO to properly deal with
594# output files written for symbols that only differ in casing, such as for two
595# classes, one named CLASS and the other named Class, and to also support
596# references to files without having to specify the exact matching casing. On
597# Windows (including Cygwin) and MacOS, users should typically set this option
598# to NO, whereas on Linux or other Unix flavors it should typically be set to
599# YES.
600# Possible values are: SYSTEM, NO and YES.
601# The default value is: SYSTEM.
602
603CASE_SENSE_NAMES = YES
604
605# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
606# their full class and namespace scopes in the documentation. If set to YES, the
607# scope will be hidden.
608# The default value is: NO.
609
610HIDE_SCOPE_NAMES = NO
611
612# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
613# append additional text to a page's title, such as Class Reference. If set to
614# YES the compound reference will be hidden.
615# The default value is: NO.
616
617HIDE_COMPOUND_REFERENCE= NO
618
619# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class
620# will show which file needs to be included to use the class.
621# The default value is: YES.
622
623SHOW_HEADERFILE = YES
624
625# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
626# the files that are included by a file in the documentation of that file.
627# The default value is: YES.
628
629SHOW_INCLUDE_FILES = YES
630
631# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
632# grouped member an include statement to the documentation, telling the reader
633# which file to include in order to use the member.
634# The default value is: NO.
635
636SHOW_GROUPED_MEMB_INC = NO
637
638# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
639# files with double quotes in the documentation rather than with sharp brackets.
640# The default value is: NO.
641
642FORCE_LOCAL_INCLUDES = NO
643
644# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
645# documentation for inline members.
646# The default value is: YES.
647
648INLINE_INFO = YES
649
650# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
651# (detailed) documentation of file and class members alphabetically by member
652# name. If set to NO, the members will appear in declaration order.
653# The default value is: YES.
654
655SORT_MEMBER_DOCS = YES
656
657# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
658# descriptions of file, namespace and class members alphabetically by member
659# name. If set to NO, the members will appear in declaration order. Note that
660# this will also influence the order of the classes in the class list.
661# The default value is: NO.
662
663SORT_BRIEF_DOCS = NO
664
665# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
666# (brief and detailed) documentation of class members so that constructors and
667# destructors are listed first. If set to NO the constructors will appear in the
668# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
669# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
670# member documentation.
671# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
672# detailed member documentation.
673# The default value is: NO.
674
675SORT_MEMBERS_CTORS_1ST = NO
676
677# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
678# of group names into alphabetical order. If set to NO the group names will
679# appear in their defined order.
680# The default value is: NO.
681
682SORT_GROUP_NAMES = NO
683
684# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
685# fully-qualified names, including namespaces. If set to NO, the class list will
686# be sorted only by class name, not including the namespace part.
687# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
688# Note: This option applies only to the class list, not to the alphabetical
689# list.
690# The default value is: NO.
691
692SORT_BY_SCOPE_NAME = NO
693
694# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
695# type resolution of all parameters of a function it will reject a match between
696# the prototype and the implementation of a member function even if there is
697# only one candidate or it is obvious which candidate to choose by doing a
698# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
699# accept a match between prototype and implementation in such cases.
700# The default value is: NO.
701
702STRICT_PROTO_MATCHING = NO
703
704# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
705# list. This list is created by putting \todo commands in the documentation.
706# The default value is: YES.
707
708GENERATE_TODOLIST = YES
709
710# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
711# list. This list is created by putting \test commands in the documentation.
712# The default value is: YES.
713
714GENERATE_TESTLIST = YES
715
716# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
717# list. This list is created by putting \bug commands in the documentation.
718# The default value is: YES.
719
720GENERATE_BUGLIST = YES
721
722# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
723# the deprecated list. This list is created by putting \deprecated commands in
724# the documentation.
725# The default value is: YES.
726
727GENERATE_DEPRECATEDLIST= YES
728
729# The ENABLED_SECTIONS tag can be used to enable conditional documentation
730# sections, marked by \if <section_label> ... \endif and \cond <section_label>
731# ... \endcond blocks.
732
733ENABLED_SECTIONS =
734
735# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
736# initial value of a variable or macro / define can have for it to appear in the
737# documentation. If the initializer consists of more lines than specified here
738# it will be hidden. Use a value of 0 to hide initializers completely. The
739# appearance of the value of individual variables and macros / defines can be
740# controlled using \showinitializer or \hideinitializer command in the
741# documentation regardless of this setting.
742# Minimum value: 0, maximum value: 10000, default value: 30.
743
744MAX_INITIALIZER_LINES = 30
745
746# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
747# the bottom of the documentation of classes and structs. If set to YES, the
748# list will mention the files that were used to generate the documentation.
749# The default value is: YES.
750
751SHOW_USED_FILES = YES
752
753# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
754# will remove the Files entry from the Quick Index and from the Folder Tree View
755# (if specified).
756# The default value is: YES.
757
758SHOW_FILES = YES
759
760# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
761# page. This will remove the Namespaces entry from the Quick Index and from the
762# Folder Tree View (if specified).
763# The default value is: YES.
764
765SHOW_NAMESPACES = YES
766
767# The FILE_VERSION_FILTER tag can be used to specify a program or script that
768# doxygen should invoke to get the current version for each file (typically from
769# the version control system). Doxygen will invoke the program by executing (via
770# popen()) the command command input-file, where command is the value of the
771# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
772# by doxygen. Whatever the program writes to standard output is used as the file
773# version. For an example see the documentation.
774
775FILE_VERSION_FILTER =
776
777# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
778# by doxygen. The layout file controls the global structure of the generated
779# output files in an output format independent way. To create the layout file
780# that represents doxygen's defaults, run doxygen with the -l option. You can
781# optionally specify a file name after the option, if omitted DoxygenLayout.xml
782# will be used as the name of the layout file. See also section "Changing the
783# layout of pages" for information.
784#
785# Note that if you run doxygen from a directory containing a file called
786# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
787# tag is left empty.
788
789LAYOUT_FILE =
790
791# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
792# the reference definitions. This must be a list of .bib files. The .bib
793# extension is automatically appended if omitted. This requires the bibtex tool
794# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
795# For LaTeX the style of the bibliography can be controlled using
796# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
797# search path. See also \cite for info how to create references.
798
799CITE_BIB_FILES =
800
801#---------------------------------------------------------------------------
802# Configuration options related to warning and progress messages
803#---------------------------------------------------------------------------
804
805# The QUIET tag can be used to turn on/off the messages that are generated to
806# standard output by doxygen. If QUIET is set to YES this implies that the
807# messages are off.
808# The default value is: NO.
809
810QUIET = NO
811
812# The WARNINGS tag can be used to turn on/off the warning messages that are
813# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
814# this implies that the warnings are on.
815#
816# Tip: Turn warnings on while writing the documentation.
817# The default value is: YES.
818
819WARNINGS = YES
820
821# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
822# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
823# will automatically be disabled.
824# The default value is: YES.
825
826WARN_IF_UNDOCUMENTED = YES
827
828# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
829# potential errors in the documentation, such as documenting some parameters in
830# a documented function twice, or documenting parameters that don't exist or
831# using markup commands wrongly.
832# The default value is: YES.
833
834WARN_IF_DOC_ERROR = YES
835
836# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete
837# function parameter documentation. If set to NO, doxygen will accept that some
838# parameters have no documentation without warning.
839# The default value is: YES.
840
841WARN_IF_INCOMPLETE_DOC = YES
842
843# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
844# are documented, but have no documentation for their parameters or return
845# value. If set to NO, doxygen will only warn about wrong parameter
846# documentation, but not about the absence of documentation. If EXTRACT_ALL is
847# set to YES then this flag will automatically be disabled. See also
848# WARN_IF_INCOMPLETE_DOC
849# The default value is: NO.
850
851WARN_NO_PARAMDOC = NO
852
853# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about
854# undocumented enumeration values. If set to NO, doxygen will accept
855# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag
856# will automatically be disabled.
857# The default value is: NO.
858
859WARN_IF_UNDOC_ENUM_VAL = NO
860
861# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
862# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
863# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
864# at the end of the doxygen process doxygen will return with a non-zero status.
865# Possible values are: NO, YES and FAIL_ON_WARNINGS.
866# The default value is: NO.
867
868WARN_AS_ERROR = NO
869
870# The WARN_FORMAT tag determines the format of the warning messages that doxygen
871# can produce. The string should contain the $file, $line, and $text tags, which
872# will be replaced by the file and line number from which the warning originated
873# and the warning text. Optionally the format may contain $version, which will
874# be replaced by the version of the file (if it could be obtained via
875# FILE_VERSION_FILTER)
876# See also: WARN_LINE_FORMAT
877# The default value is: $file:$line: $text.
878
879WARN_FORMAT = "$file:$line: $text"
880
881# In the $text part of the WARN_FORMAT command it is possible that a reference
882# to a more specific place is given. To make it easier to jump to this place
883# (outside of doxygen) the user can define a custom "cut" / "paste" string.
884# Example:
885# WARN_LINE_FORMAT = "'vi $file +$line'"
886# See also: WARN_FORMAT
887# The default value is: at line $line of file $file.
888
889WARN_LINE_FORMAT = "at line $line of file $file"
890
891# The WARN_LOGFILE tag can be used to specify a file to which warning and error
892# messages should be written. If left blank the output is written to standard
893# error (stderr). In case the file specified cannot be opened for writing the
894# warning and error messages are written to standard error. When as file - is
895# specified the warning and error messages are written to standard output
896# (stdout).
897
898WARN_LOGFILE =
899
900#---------------------------------------------------------------------------
901# Configuration options related to the input files
902#---------------------------------------------------------------------------
903
904# The INPUT tag is used to specify the files and/or directories that contain
905# documented source files. You may enter file names like myfile.cpp or
906# directories like /usr/src/myproject. Separate the files or directories with
907# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
908# Note: If this tag is empty the current directory is searched.
909
910INPUT = ../hidapi \
911 ./main_page.md
912
913# This tag can be used to specify the character encoding of the source files
914# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
915# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
916# documentation (see:
917# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
918# See also: INPUT_FILE_ENCODING
919# The default value is: UTF-8.
920
921INPUT_ENCODING = UTF-8
922
923# This tag can be used to specify the character encoding of the source files
924# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify
925# character encoding on a per file pattern basis. Doxygen will compare the file
926# name with each pattern and apply the encoding instead of the default
927# INPUT_ENCODING) if there is a match. The character encodings are a list of the
928# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding
929# "INPUT_ENCODING" for further information on supported encodings.
930
931INPUT_FILE_ENCODING =
932
933# If the value of the INPUT tag contains directories, you can use the
934# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
935# *.h) to filter out the source-files in the directories.
936#
937# Note that for custom extensions or not directly supported extensions you also
938# need to set EXTENSION_MAPPING for the extension otherwise the files are not
939# read by doxygen.
940#
941# Note the list of default checked file patterns might differ from the list of
942# default file extension mappings.
943#
944# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
945# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
946# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,
947# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C
948# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
949# *.vhdl, *.ucf, *.qsf and *.ice.
950
951FILE_PATTERNS =
952
953# The RECURSIVE tag can be used to specify whether or not subdirectories should
954# be searched for input files as well.
955# The default value is: NO.
956
957RECURSIVE = NO
958
959# The EXCLUDE tag can be used to specify files and/or directories that should be
960# excluded from the INPUT source files. This way you can easily exclude a
961# subdirectory from a directory tree whose root is specified with the INPUT tag.
962#
963# Note that relative paths are relative to the directory from which doxygen is
964# run.
965
966EXCLUDE =
967
968# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
969# directories that are symbolic links (a Unix file system feature) are excluded
970# from the input.
971# The default value is: NO.
972
973EXCLUDE_SYMLINKS = NO
974
975# If the value of the INPUT tag contains directories, you can use the
976# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
977# certain files from those directories.
978#
979# Note that the wildcards are matched against the file with absolute path, so to
980# exclude all test directories for example use the pattern */test/*
981
982EXCLUDE_PATTERNS =
983
984# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
985# (namespaces, classes, functions, etc.) that should be excluded from the
986# output. The symbol name can be a fully qualified name, a word, or if the
987# wildcard * is used, a substring. Examples: ANamespace, AClass,
988# ANamespace::AClass, ANamespace::*Test
989#
990# Note that the wildcards are matched against the file with absolute path, so to
991# exclude all test directories use the pattern */test/*
992
993EXCLUDE_SYMBOLS = HID_API_AS_STR_IMPL \
994 HID_API_AS_STR \
995 HID_API_TO_VERSION_STR
996
997# The EXAMPLE_PATH tag can be used to specify one or more files or directories
998# that contain example code fragments that are included (see the \include
999# command).
1000
1001EXAMPLE_PATH = ../hidtest
1002
1003# If the value of the EXAMPLE_PATH tag contains directories, you can use the
1004# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
1005# *.h) to filter out the source-files in the directories. If left blank all
1006# files are included.
1007
1008EXAMPLE_PATTERNS = *.c
1009
1010# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
1011# searched for input files to be used with the \include or \dontinclude commands
1012# irrespective of the value of the RECURSIVE tag.
1013# The default value is: NO.
1014
1015EXAMPLE_RECURSIVE = NO
1016
1017# The IMAGE_PATH tag can be used to specify one or more files or directories
1018# that contain images that are to be included in the documentation (see the
1019# \image command).
1020
1021IMAGE_PATH =
1022
1023# The INPUT_FILTER tag can be used to specify a program that doxygen should
1024# invoke to filter for each input file. Doxygen will invoke the filter program
1025# by executing (via popen()) the command:
1026#
1027# <filter> <input-file>
1028#
1029# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
1030# name of an input file. Doxygen will then use the output that the filter
1031# program writes to standard output. If FILTER_PATTERNS is specified, this tag
1032# will be ignored.
1033#
1034# Note that the filter must not add or remove lines; it is applied before the
1035# code is scanned, but not when the output code is generated. If lines are added
1036# or removed, the anchors will not be placed correctly.
1037#
1038# Note that doxygen will use the data processed and written to standard output
1039# for further processing, therefore nothing else, like debug statements or used
1040# commands (so in case of a Windows batch file always use @echo OFF), should be
1041# written to standard output.
1042#
1043# Note that for custom extensions or not directly supported extensions you also
1044# need to set EXTENSION_MAPPING for the extension otherwise the files are not
1045# properly processed by doxygen.
1046
1047INPUT_FILTER =
1048
1049# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
1050# basis. Doxygen will compare the file name with each pattern and apply the
1051# filter if there is a match. The filters are a list of the form: pattern=filter
1052# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
1053# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
1054# patterns match the file name, INPUT_FILTER is applied.
1055#
1056# Note that for custom extensions or not directly supported extensions you also
1057# need to set EXTENSION_MAPPING for the extension otherwise the files are not
1058# properly processed by doxygen.
1059
1060FILTER_PATTERNS =
1061
1062# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
1063# INPUT_FILTER) will also be used to filter the input files that are used for
1064# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
1065# The default value is: NO.
1066
1067FILTER_SOURCE_FILES = NO
1068
1069# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
1070# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
1071# it is also possible to disable source filtering for a specific pattern using
1072# *.ext= (so without naming a filter).
1073# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
1074
1075FILTER_SOURCE_PATTERNS =
1076
1077# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
1078# is part of the input, its contents will be placed on the main page
1079# (index.html). This can be useful if you have a project on for instance GitHub
1080# and want to reuse the introduction page also for the doxygen output.
1081
1082USE_MDFILE_AS_MAINPAGE = main_page.md
1083
1084# The Fortran standard specifies that for fixed formatted Fortran code all
1085# characters from position 72 are to be considered as comment. A common
1086# extension is to allow longer lines before the automatic comment starts. The
1087# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can
1088# be processed before the automatic comment starts.
1089# Minimum value: 7, maximum value: 10000, default value: 72.
1090
1091FORTRAN_COMMENT_AFTER = 72
1092
1093#---------------------------------------------------------------------------
1094# Configuration options related to source browsing
1095#---------------------------------------------------------------------------
1096
1097# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
1098# generated. Documented entities will be cross-referenced with these sources.
1099#
1100# Note: To get rid of all source code in the generated output, make sure that
1101# also VERBATIM_HEADERS is set to NO.
1102# The default value is: NO.
1103
1104SOURCE_BROWSER = NO
1105
1106# Setting the INLINE_SOURCES tag to YES will include the body of functions,
1107# classes and enums directly into the documentation.
1108# The default value is: NO.
1109
1110INLINE_SOURCES = NO
1111
1112# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
1113# special comment blocks from generated source code fragments. Normal C, C++ and
1114# Fortran comments will always remain visible.
1115# The default value is: YES.
1116
1117STRIP_CODE_COMMENTS = YES
1118
1119# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
1120# entity all documented functions referencing it will be listed.
1121# The default value is: NO.
1122
1123REFERENCED_BY_RELATION = NO
1124
1125# If the REFERENCES_RELATION tag is set to YES then for each documented function
1126# all documented entities called/used by that function will be listed.
1127# The default value is: NO.
1128
1129REFERENCES_RELATION = NO
1130
1131# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
1132# to YES then the hyperlinks from functions in REFERENCES_RELATION and
1133# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
1134# link to the documentation.
1135# The default value is: YES.
1136
1137REFERENCES_LINK_SOURCE = YES
1138
1139# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
1140# source code will show a tooltip with additional information such as prototype,
1141# brief description and links to the definition and documentation. Since this
1142# will make the HTML file larger and loading of large files a bit slower, you
1143# can opt to disable this feature.
1144# The default value is: YES.
1145# This tag requires that the tag SOURCE_BROWSER is set to YES.
1146
1147SOURCE_TOOLTIPS = YES
1148
1149# If the USE_HTAGS tag is set to YES then the references to source code will
1150# point to the HTML generated by the htags(1) tool instead of doxygen built-in
1151# source browser. The htags tool is part of GNU's global source tagging system
1152# (see https://www.gnu.org/software/global/global.html). You will need version
1153# 4.8.6 or higher.
1154#
1155# To use it do the following:
1156# - Install the latest version of global
1157# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
1158# - Make sure the INPUT points to the root of the source tree
1159# - Run doxygen as normal
1160#
1161# Doxygen will invoke htags (and that will in turn invoke gtags), so these
1162# tools must be available from the command line (i.e. in the search path).
1163#
1164# The result: instead of the source browser generated by doxygen, the links to
1165# source code will now point to the output of htags.
1166# The default value is: NO.
1167# This tag requires that the tag SOURCE_BROWSER is set to YES.
1168
1169USE_HTAGS = NO
1170
1171# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
1172# verbatim copy of the header file for each class for which an include is
1173# specified. Set to NO to disable this.
1174# See also: Section \class.
1175# The default value is: YES.
1176
1177VERBATIM_HEADERS = YES
1178
1179# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
1180# clang parser (see:
1181# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
1182# performance. This can be particularly helpful with template rich C++ code for
1183# which doxygen's built-in parser lacks the necessary type information.
1184# Note: The availability of this option depends on whether or not doxygen was
1185# generated with the -Duse_libclang=ON option for CMake.
1186# The default value is: NO.
1187
1188CLANG_ASSISTED_PARSING = NO
1189
1190# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS
1191# tag is set to YES then doxygen will add the directory of each input to the
1192# include path.
1193# The default value is: YES.
1194# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
1195
1196CLANG_ADD_INC_PATHS = YES
1197
1198# If clang assisted parsing is enabled you can provide the compiler with command
1199# line options that you would normally use when invoking the compiler. Note that
1200# the include paths will already be set by doxygen for the files and directories
1201# specified with INPUT and INCLUDE_PATH.
1202# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
1203
1204CLANG_OPTIONS =
1205
1206# If clang assisted parsing is enabled you can provide the clang parser with the
1207# path to the directory containing a file called compile_commands.json. This
1208# file is the compilation database (see:
1209# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
1210# options used when the source files were built. This is equivalent to
1211# specifying the -p option to a clang tool, such as clang-check. These options
1212# will then be passed to the parser. Any options specified with CLANG_OPTIONS
1213# will be added as well.
1214# Note: The availability of this option depends on whether or not doxygen was
1215# generated with the -Duse_libclang=ON option for CMake.
1216
1217CLANG_DATABASE_PATH =
1218
1219#---------------------------------------------------------------------------
1220# Configuration options related to the alphabetical class index
1221#---------------------------------------------------------------------------
1222
1223# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
1224# compounds will be generated. Enable this if the project contains a lot of
1225# classes, structs, unions or interfaces.
1226# The default value is: YES.
1227
1228ALPHABETICAL_INDEX = YES
1229
1230# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes)
1231# that should be ignored while generating the index headers. The IGNORE_PREFIX
1232# tag works for classes, function and member names. The entity will be placed in
1233# the alphabetical list under the first letter of the entity name that remains
1234# after removing the prefix.
1235# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
1236
1237IGNORE_PREFIX =
1238
1239#---------------------------------------------------------------------------
1240# Configuration options related to the HTML output
1241#---------------------------------------------------------------------------
1242
1243# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
1244# The default value is: YES.
1245
1246GENERATE_HTML = YES
1247
1248# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
1249# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
1250# it.
1251# The default directory is: html.
1252# This tag requires that the tag GENERATE_HTML is set to YES.
1253
1254HTML_OUTPUT = html
1255
1256# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
1257# generated HTML page (for example: .htm, .php, .asp).
1258# The default value is: .html.
1259# This tag requires that the tag GENERATE_HTML is set to YES.
1260
1261HTML_FILE_EXTENSION = .html
1262
1263# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
1264# each generated HTML page. If the tag is left blank doxygen will generate a
1265# standard header.
1266#
1267# To get valid HTML the header file that includes any scripts and style sheets
1268# that doxygen needs, which is dependent on the configuration options used (e.g.
1269# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
1270# default header using
1271# doxygen -w html new_header.html new_footer.html new_stylesheet.css
1272# YourConfigFile
1273# and then modify the file new_header.html. See also section "Doxygen usage"
1274# for information on how to generate the default header that doxygen normally
1275# uses.
1276# Note: The header is subject to change so you typically have to regenerate the
1277# default header when upgrading to a newer version of doxygen. For a description
1278# of the possible markers and block names see the documentation.
1279# This tag requires that the tag GENERATE_HTML is set to YES.
1280
1281HTML_HEADER =
1282
1283# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
1284# generated HTML page. If the tag is left blank doxygen will generate a standard
1285# footer. See HTML_HEADER for more information on how to generate a default
1286# footer and what special commands can be used inside the footer. See also
1287# section "Doxygen usage" for information on how to generate the default footer
1288# that doxygen normally uses.
1289# This tag requires that the tag GENERATE_HTML is set to YES.
1290
1291HTML_FOOTER =
1292
1293# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
1294# sheet that is used by each HTML page. It can be used to fine-tune the look of
1295# the HTML output. If left blank doxygen will generate a default style sheet.
1296# See also section "Doxygen usage" for information on how to generate the style
1297# sheet that doxygen normally uses.
1298# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
1299# it is more robust and this tag (HTML_STYLESHEET) will in the future become
1300# obsolete.
1301# This tag requires that the tag GENERATE_HTML is set to YES.
1302
1303HTML_STYLESHEET =
1304
1305# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
1306# cascading style sheets that are included after the standard style sheets
1307# created by doxygen. Using this option one can overrule certain style aspects.
1308# This is preferred over using HTML_STYLESHEET since it does not replace the
1309# standard style sheet and is therefore more robust against future updates.
1310# Doxygen will copy the style sheet files to the output directory.
1311# Note: The order of the extra style sheet files is of importance (e.g. the last
1312# style sheet in the list overrules the setting of the previous ones in the
1313# list).
1314# Note: Since the styling of scrollbars can currently not be overruled in
1315# Webkit/Chromium, the styling will be left out of the default doxygen.css if
1316# one or more extra stylesheets have been specified. So if scrollbar
1317# customization is desired it has to be added explicitly. For an example see the
1318# documentation.
1319# This tag requires that the tag GENERATE_HTML is set to YES.
1320
1321HTML_EXTRA_STYLESHEET =
1322
1323# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
1324# other source files which should be copied to the HTML output directory. Note
1325# that these files will be copied to the base HTML output directory. Use the
1326# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
1327# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
1328# files will be copied as-is; there are no commands or markers available.
1329# This tag requires that the tag GENERATE_HTML is set to YES.
1330
1331HTML_EXTRA_FILES =
1332
1333# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
1334# should be rendered with a dark or light theme.
1335# Possible values are: LIGHT always generate light mode output, DARK always
1336# generate dark mode output, AUTO_LIGHT automatically set the mode according to
1337# the user preference, use light mode if no preference is set (the default),
1338# AUTO_DARK automatically set the mode according to the user preference, use
1339# dark mode if no preference is set and TOGGLE allow to user to switch between
1340# light and dark mode via a button.
1341# The default value is: AUTO_LIGHT.
1342# This tag requires that the tag GENERATE_HTML is set to YES.
1343
1344HTML_COLORSTYLE = AUTO_LIGHT
1345
1346# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
1347# will adjust the colors in the style sheet and background images according to
1348# this color. Hue is specified as an angle on a color-wheel, see
1349# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
1350# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
1351# purple, and 360 is red again.
1352# Minimum value: 0, maximum value: 359, default value: 220.
1353# This tag requires that the tag GENERATE_HTML is set to YES.
1354
1355HTML_COLORSTYLE_HUE = 220
1356
1357# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
1358# in the HTML output. For a value of 0 the output will use gray-scales only. A
1359# value of 255 will produce the most vivid colors.
1360# Minimum value: 0, maximum value: 255, default value: 100.
1361# This tag requires that the tag GENERATE_HTML is set to YES.
1362
1363HTML_COLORSTYLE_SAT = 100
1364
1365# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
1366# luminance component of the colors in the HTML output. Values below 100
1367# gradually make the output lighter, whereas values above 100 make the output
1368# darker. The value divided by 100 is the actual gamma applied, so 80 represents
1369# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
1370# change the gamma.
1371# Minimum value: 40, maximum value: 240, default value: 80.
1372# This tag requires that the tag GENERATE_HTML is set to YES.
1373
1374HTML_COLORSTYLE_GAMMA = 80
1375
1376# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
1377# page will contain the date and time when the page was generated. Setting this
1378# to YES can help to show when doxygen was last run and thus if the
1379# documentation is up to date.
1380# The default value is: NO.
1381# This tag requires that the tag GENERATE_HTML is set to YES.
1382
1383HTML_TIMESTAMP = YES
1384
1385# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
1386# documentation will contain a main index with vertical navigation menus that
1387# are dynamically created via JavaScript. If disabled, the navigation index will
1388# consists of multiple levels of tabs that are statically embedded in every HTML
1389# page. Disable this option to support browsers that do not have JavaScript,
1390# like the Qt help browser.
1391# The default value is: YES.
1392# This tag requires that the tag GENERATE_HTML is set to YES.
1393
1394HTML_DYNAMIC_MENUS = YES
1395
1396# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
1397# documentation will contain sections that can be hidden and shown after the
1398# page has loaded.
1399# The default value is: NO.
1400# This tag requires that the tag GENERATE_HTML is set to YES.
1401
1402HTML_DYNAMIC_SECTIONS = NO
1403
1404# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
1405# shown in the various tree structured indices initially; the user can expand
1406# and collapse entries dynamically later on. Doxygen will expand the tree to
1407# such a level that at most the specified number of entries are visible (unless
1408# a fully collapsed tree already exceeds this amount). So setting the number of
1409# entries 1 will produce a full collapsed tree by default. 0 is a special value
1410# representing an infinite number of entries and will result in a full expanded
1411# tree by default.
1412# Minimum value: 0, maximum value: 9999, default value: 100.
1413# This tag requires that the tag GENERATE_HTML is set to YES.
1414
1415HTML_INDEX_NUM_ENTRIES = 100
1416
1417# If the GENERATE_DOCSET tag is set to YES, additional index files will be
1418# generated that can be used as input for Apple's Xcode 3 integrated development
1419# environment (see:
1420# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
1421# create a documentation set, doxygen will generate a Makefile in the HTML
1422# output directory. Running make will produce the docset in that directory and
1423# running make install will install the docset in
1424# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
1425# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
1426# genXcode/_index.html for more information.
1427# The default value is: NO.
1428# This tag requires that the tag GENERATE_HTML is set to YES.
1429
1430GENERATE_DOCSET = NO
1431
1432# This tag determines the name of the docset feed. A documentation feed provides
1433# an umbrella under which multiple documentation sets from a single provider
1434# (such as a company or product suite) can be grouped.
1435# The default value is: Doxygen generated docs.
1436# This tag requires that the tag GENERATE_DOCSET is set to YES.
1437
1438DOCSET_FEEDNAME = "Doxygen generated docs"
1439
1440# This tag determines the URL of the docset feed. A documentation feed provides
1441# an umbrella under which multiple documentation sets from a single provider
1442# (such as a company or product suite) can be grouped.
1443# This tag requires that the tag GENERATE_DOCSET is set to YES.
1444
1445DOCSET_FEEDURL =
1446
1447# This tag specifies a string that should uniquely identify the documentation
1448# set bundle. This should be a reverse domain-name style string, e.g.
1449# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
1450# The default value is: org.doxygen.Project.
1451# This tag requires that the tag GENERATE_DOCSET is set to YES.
1452
1453DOCSET_BUNDLE_ID = org.doxygen.Project
1454
1455# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
1456# the documentation publisher. This should be a reverse domain-name style
1457# string, e.g. com.mycompany.MyDocSet.documentation.
1458# The default value is: org.doxygen.Publisher.
1459# This tag requires that the tag GENERATE_DOCSET is set to YES.
1460
1461DOCSET_PUBLISHER_ID = org.doxygen.Publisher
1462
1463# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
1464# The default value is: Publisher.
1465# This tag requires that the tag GENERATE_DOCSET is set to YES.
1466
1467DOCSET_PUBLISHER_NAME = Publisher
1468
1469# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
1470# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
1471# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
1472# on Windows. In the beginning of 2021 Microsoft took the original page, with
1473# a.o. the download links, offline the HTML help workshop was already many years
1474# in maintenance mode). You can download the HTML help workshop from the web
1475# archives at Installation executable (see:
1476# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo
1477# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe).
1478#
1479# The HTML Help Workshop contains a compiler that can convert all HTML output
1480# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
1481# files are now used as the Windows 98 help format, and will replace the old
1482# Windows help format (.hlp) on all Windows platforms in the future. Compressed
1483# HTML files also contain an index, a table of contents, and you can search for
1484# words in the documentation. The HTML workshop also contains a viewer for
1485# compressed HTML files.
1486# The default value is: NO.
1487# This tag requires that the tag GENERATE_HTML is set to YES.
1488
1489GENERATE_HTMLHELP = NO
1490
1491# The CHM_FILE tag can be used to specify the file name of the resulting .chm
1492# file. You can add a path in front of the file if the result should not be
1493# written to the html output directory.
1494# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1495
1496CHM_FILE =
1497
1498# The HHC_LOCATION tag can be used to specify the location (absolute path
1499# including file name) of the HTML help compiler (hhc.exe). If non-empty,
1500# doxygen will try to run the HTML help compiler on the generated index.hhp.
1501# The file has to be specified with full path.
1502# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1503
1504HHC_LOCATION =
1505
1506# The GENERATE_CHI flag controls if a separate .chi index file is generated
1507# (YES) or that it should be included in the main .chm file (NO).
1508# The default value is: NO.
1509# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1510
1511GENERATE_CHI = NO
1512
1513# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
1514# and project file content.
1515# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1516
1517CHM_INDEX_ENCODING =
1518
1519# The BINARY_TOC flag controls whether a binary table of contents is generated
1520# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
1521# enables the Previous and Next buttons.
1522# The default value is: NO.
1523# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1524
1525BINARY_TOC = NO
1526
1527# The TOC_EXPAND flag can be set to YES to add extra items for group members to
1528# the table of contents of the HTML help documentation and to the tree view.
1529# The default value is: NO.
1530# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
1531
1532TOC_EXPAND = NO
1533
1534# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
1535# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
1536# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
1537# (.qch) of the generated HTML documentation.
1538# The default value is: NO.
1539# This tag requires that the tag GENERATE_HTML is set to YES.
1540
1541GENERATE_QHP = NO
1542
1543# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
1544# the file name of the resulting .qch file. The path specified is relative to
1545# the HTML output folder.
1546# This tag requires that the tag GENERATE_QHP is set to YES.
1547
1548QCH_FILE =
1549
1550# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
1551# Project output. For more information please see Qt Help Project / Namespace
1552# (see:
1553# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
1554# The default value is: org.doxygen.Project.
1555# This tag requires that the tag GENERATE_QHP is set to YES.
1556
1557QHP_NAMESPACE = org.doxygen.Project
1558
1559# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
1560# Help Project output. For more information please see Qt Help Project / Virtual
1561# Folders (see:
1562# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
1563# The default value is: doc.
1564# This tag requires that the tag GENERATE_QHP is set to YES.
1565
1566QHP_VIRTUAL_FOLDER = doc
1567
1568# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
1569# filter to add. For more information please see Qt Help Project / Custom
1570# Filters (see:
1571# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
1572# This tag requires that the tag GENERATE_QHP is set to YES.
1573
1574QHP_CUST_FILTER_NAME =
1575
1576# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
1577# custom filter to add. For more information please see Qt Help Project / Custom
1578# Filters (see:
1579# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
1580# This tag requires that the tag GENERATE_QHP is set to YES.
1581
1582QHP_CUST_FILTER_ATTRS =
1583
1584# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
1585# project's filter section matches. Qt Help Project / Filter Attributes (see:
1586# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
1587# This tag requires that the tag GENERATE_QHP is set to YES.
1588
1589QHP_SECT_FILTER_ATTRS =
1590
1591# The QHG_LOCATION tag can be used to specify the location (absolute path
1592# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
1593# run qhelpgenerator on the generated .qhp file.
1594# This tag requires that the tag GENERATE_QHP is set to YES.
1595
1596QHG_LOCATION =
1597
1598# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
1599# generated, together with the HTML files, they form an Eclipse help plugin. To
1600# install this plugin and make it available under the help contents menu in
1601# Eclipse, the contents of the directory containing the HTML and XML files needs
1602# to be copied into the plugins directory of eclipse. The name of the directory
1603# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
1604# After copying Eclipse needs to be restarted before the help appears.
1605# The default value is: NO.
1606# This tag requires that the tag GENERATE_HTML is set to YES.
1607
1608GENERATE_ECLIPSEHELP = NO
1609
1610# A unique identifier for the Eclipse help plugin. When installing the plugin
1611# the directory name containing the HTML and XML files should also have this
1612# name. Each documentation set should have its own identifier.
1613# The default value is: org.doxygen.Project.
1614# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
1615
1616ECLIPSE_DOC_ID = org.doxygen.Project
1617
1618# If you want full control over the layout of the generated HTML pages it might
1619# be necessary to disable the index and replace it with your own. The
1620# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
1621# of each HTML page. A value of NO enables the index and the value YES disables
1622# it. Since the tabs in the index contain the same information as the navigation
1623# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
1624# The default value is: NO.
1625# This tag requires that the tag GENERATE_HTML is set to YES.
1626
1627DISABLE_INDEX = NO
1628
1629# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
1630# structure should be generated to display hierarchical information. If the tag
1631# value is set to YES, a side panel will be generated containing a tree-like
1632# index structure (just like the one that is generated for HTML Help). For this
1633# to work a browser that supports JavaScript, DHTML, CSS and frames is required
1634# (i.e. any modern browser). Windows users are probably better off using the
1635# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
1636# further fine tune the look of the index (see "Fine-tuning the output"). As an
1637# example, the default style sheet generated by doxygen has an example that
1638# shows how to put an image at the root of the tree instead of the PROJECT_NAME.
1639# Since the tree basically has the same information as the tab index, you could
1640# consider setting DISABLE_INDEX to YES when enabling this option.
1641# The default value is: NO.
1642# This tag requires that the tag GENERATE_HTML is set to YES.
1643
1644GENERATE_TREEVIEW = NO
1645
1646# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
1647# FULL_SIDEBAR option determines if the side bar is limited to only the treeview
1648# area (value NO) or if it should extend to the full height of the window (value
1649# YES). Setting this to YES gives a layout similar to
1650# https://docs.readthedocs.io with more room for contents, but less room for the
1651# project logo, title, and description. If either GENERATE_TREEVIEW or
1652# DISABLE_INDEX is set to NO, this option has no effect.
1653# The default value is: NO.
1654# This tag requires that the tag GENERATE_HTML is set to YES.
1655
1656FULL_SIDEBAR = NO
1657
1658# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
1659# doxygen will group on one line in the generated HTML documentation.
1660#
1661# Note that a value of 0 will completely suppress the enum values from appearing
1662# in the overview section.
1663# Minimum value: 0, maximum value: 20, default value: 4.
1664# This tag requires that the tag GENERATE_HTML is set to YES.
1665
1666ENUM_VALUES_PER_LINE = 4
1667
1668# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
1669# to set the initial width (in pixels) of the frame in which the tree is shown.
1670# Minimum value: 0, maximum value: 1500, default value: 250.
1671# This tag requires that the tag GENERATE_HTML is set to YES.
1672
1673TREEVIEW_WIDTH = 250
1674
1675# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
1676# external symbols imported via tag files in a separate window.
1677# The default value is: NO.
1678# This tag requires that the tag GENERATE_HTML is set to YES.
1679
1680EXT_LINKS_IN_WINDOW = NO
1681
1682# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email
1683# addresses.
1684# The default value is: YES.
1685# This tag requires that the tag GENERATE_HTML is set to YES.
1686
1687OBFUSCATE_EMAILS = YES
1688
1689# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
1690# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
1691# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
1692# the HTML output. These images will generally look nicer at scaled resolutions.
1693# Possible values are: png (the default) and svg (looks nicer but requires the
1694# pdf2svg or inkscape tool).
1695# The default value is: png.
1696# This tag requires that the tag GENERATE_HTML is set to YES.
1697
1698HTML_FORMULA_FORMAT = png
1699
1700# Use this tag to change the font size of LaTeX formulas included as images in
1701# the HTML documentation. When you change the font size after a successful
1702# doxygen run you need to manually remove any form_*.png images from the HTML
1703# output directory to force them to be regenerated.
1704# Minimum value: 8, maximum value: 50, default value: 10.
1705# This tag requires that the tag GENERATE_HTML is set to YES.
1706
1707FORMULA_FONTSIZE = 10
1708
1709# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
1710# to create new LaTeX commands to be used in formulas as building blocks. See
1711# the section "Including formulas" for details.
1712
1713FORMULA_MACROFILE =
1714
1715# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
1716# https://www.mathjax.org) which uses client side JavaScript for the rendering
1717# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
1718# installed or if you want to formulas look prettier in the HTML output. When
1719# enabled you may also need to install MathJax separately and configure the path
1720# to it using the MATHJAX_RELPATH option.
1721# The default value is: NO.
1722# This tag requires that the tag GENERATE_HTML is set to YES.
1723
1724USE_MATHJAX = NO
1725
1726# With MATHJAX_VERSION it is possible to specify the MathJax version to be used.
1727# Note that the different versions of MathJax have different requirements with
1728# regards to the different settings, so it is possible that also other MathJax
1729# settings have to be changed when switching between the different MathJax
1730# versions.
1731# Possible values are: MathJax_2 and MathJax_3.
1732# The default value is: MathJax_2.
1733# This tag requires that the tag USE_MATHJAX is set to YES.
1734
1735MATHJAX_VERSION = MathJax_2
1736
1737# When MathJax is enabled you can set the default output format to be used for
1738# the MathJax output. For more details about the output format see MathJax
1739# version 2 (see:
1740# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3
1741# (see:
1742# http://docs.mathjax.org/en/latest/web/components/output.html).
1743# Possible values are: HTML-CSS (which is slower, but has the best
1744# compatibility. This is the name for Mathjax version 2, for MathJax version 3
1745# this will be translated into chtml), NativeMML (i.e. MathML. Only supported
1746# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This
1747# is the name for Mathjax version 3, for MathJax version 2 this will be
1748# translated into HTML-CSS) and SVG.
1749# The default value is: HTML-CSS.
1750# This tag requires that the tag USE_MATHJAX is set to YES.
1751
1752MATHJAX_FORMAT = HTML-CSS
1753
1754# When MathJax is enabled you need to specify the location relative to the HTML
1755# output directory using the MATHJAX_RELPATH option. The destination directory
1756# should contain the MathJax.js script. For instance, if the mathjax directory
1757# is located at the same level as the HTML output directory, then
1758# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
1759# Content Delivery Network so you can quickly see the result without installing
1760# MathJax. However, it is strongly recommended to install a local copy of
1761# MathJax from https://www.mathjax.org before deployment. The default value is:
1762# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2
1763# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3
1764# This tag requires that the tag USE_MATHJAX is set to YES.
1765
1766MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/
1767
1768# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
1769# extension names that should be enabled during MathJax rendering. For example
1770# for MathJax version 2 (see
1771# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
1772# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
1773# For example for MathJax version 3 (see
1774# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
1775# MATHJAX_EXTENSIONS = ams
1776# This tag requires that the tag USE_MATHJAX is set to YES.
1777
1778MATHJAX_EXTENSIONS =
1779
1780# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
1781# of code that will be used on startup of the MathJax code. See the MathJax site
1782# (see:
1783# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
1784# example see the documentation.
1785# This tag requires that the tag USE_MATHJAX is set to YES.
1786
1787MATHJAX_CODEFILE =
1788
1789# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
1790# the HTML output. The underlying search engine uses javascript and DHTML and
1791# should work on any modern browser. Note that when using HTML help
1792# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
1793# there is already a search function so this one should typically be disabled.
1794# For large projects the javascript based search engine can be slow, then
1795# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
1796# search using the keyboard; to jump to the search box use <access key> + S
1797# (what the <access key> is depends on the OS and browser, but it is typically
1798# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
1799# key> to jump into the search results window, the results can be navigated
1800# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
1801# the search. The filter options can be selected when the cursor is inside the
1802# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
1803# to select a filter and <Enter> or <escape> to activate or cancel the filter
1804# option.
1805# The default value is: YES.
1806# This tag requires that the tag GENERATE_HTML is set to YES.
1807
1808SEARCHENGINE = YES
1809
1810# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
1811# implemented using a web server instead of a web client using JavaScript. There
1812# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
1813# setting. When disabled, doxygen will generate a PHP script for searching and
1814# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
1815# and searching needs to be provided by external tools. See the section
1816# "External Indexing and Searching" for details.
1817# The default value is: NO.
1818# This tag requires that the tag SEARCHENGINE is set to YES.
1819
1820SERVER_BASED_SEARCH = NO
1821
1822# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
1823# script for searching. Instead the search results are written to an XML file
1824# which needs to be processed by an external indexer. Doxygen will invoke an
1825# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
1826# search results.
1827#
1828# Doxygen ships with an example indexer (doxyindexer) and search engine
1829# (doxysearch.cgi) which are based on the open source search engine library
1830# Xapian (see:
1831# https://xapian.org/).
1832#
1833# See the section "External Indexing and Searching" for details.
1834# The default value is: NO.
1835# This tag requires that the tag SEARCHENGINE is set to YES.
1836
1837EXTERNAL_SEARCH = NO
1838
1839# The SEARCHENGINE_URL should point to a search engine hosted by a web server
1840# which will return the search results when EXTERNAL_SEARCH is enabled.
1841#
1842# Doxygen ships with an example indexer (doxyindexer) and search engine
1843# (doxysearch.cgi) which are based on the open source search engine library
1844# Xapian (see:
1845# https://xapian.org/). See the section "External Indexing and Searching" for
1846# details.
1847# This tag requires that the tag SEARCHENGINE is set to YES.
1848
1849SEARCHENGINE_URL =
1850
1851# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
1852# search data is written to a file for indexing by an external tool. With the
1853# SEARCHDATA_FILE tag the name of this file can be specified.
1854# The default file is: searchdata.xml.
1855# This tag requires that the tag SEARCHENGINE is set to YES.
1856
1857SEARCHDATA_FILE = searchdata.xml
1858
1859# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
1860# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
1861# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
1862# projects and redirect the results back to the right project.
1863# This tag requires that the tag SEARCHENGINE is set to YES.
1864
1865EXTERNAL_SEARCH_ID =
1866
1867# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
1868# projects other than the one defined by this configuration file, but that are
1869# all added to the same external search index. Each project needs to have a
1870# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
1871# to a relative location where the documentation can be found. The format is:
1872# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
1873# This tag requires that the tag SEARCHENGINE is set to YES.
1874
1875EXTRA_SEARCH_MAPPINGS =
1876
1877#---------------------------------------------------------------------------
1878# Configuration options related to the LaTeX output
1879#---------------------------------------------------------------------------
1880
1881# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
1882# The default value is: YES.
1883
1884GENERATE_LATEX = NO
1885
1886# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
1887# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
1888# it.
1889# The default directory is: latex.
1890# This tag requires that the tag GENERATE_LATEX is set to YES.
1891
1892LATEX_OUTPUT = latex
1893
1894# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
1895# invoked.
1896#
1897# Note that when not enabling USE_PDFLATEX the default is latex when enabling
1898# USE_PDFLATEX the default is pdflatex and when in the later case latex is
1899# chosen this is overwritten by pdflatex. For specific output languages the
1900# default can have been set differently, this depends on the implementation of
1901# the output language.
1902# This tag requires that the tag GENERATE_LATEX is set to YES.
1903
1904LATEX_CMD_NAME = latex
1905
1906# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
1907# index for LaTeX.
1908# Note: This tag is used in the Makefile / make.bat.
1909# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
1910# (.tex).
1911# The default file is: makeindex.
1912# This tag requires that the tag GENERATE_LATEX is set to YES.
1913
1914MAKEINDEX_CMD_NAME = makeindex
1915
1916# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
1917# generate index for LaTeX. In case there is no backslash (\) as first character
1918# it will be automatically added in the LaTeX code.
1919# Note: This tag is used in the generated output file (.tex).
1920# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
1921# The default value is: makeindex.
1922# This tag requires that the tag GENERATE_LATEX is set to YES.
1923
1924LATEX_MAKEINDEX_CMD = \makeindex
1925
1926# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
1927# documents. This may be useful for small projects and may help to save some
1928# trees in general.
1929# The default value is: NO.
1930# This tag requires that the tag GENERATE_LATEX is set to YES.
1931
1932COMPACT_LATEX = NO
1933
1934# The PAPER_TYPE tag can be used to set the paper type that is used by the
1935# printer.
1936# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
1937# 14 inches) and executive (7.25 x 10.5 inches).
1938# The default value is: a4.
1939# This tag requires that the tag GENERATE_LATEX is set to YES.
1940
1941PAPER_TYPE = a4
1942
1943# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
1944# that should be included in the LaTeX output. The package can be specified just
1945# by its name or with the correct syntax as to be used with the LaTeX
1946# \usepackage command. To get the times font for instance you can specify :
1947# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
1948# To use the option intlimits with the amsmath package you can specify:
1949# EXTRA_PACKAGES=[intlimits]{amsmath}
1950# If left blank no extra packages will be included.
1951# This tag requires that the tag GENERATE_LATEX is set to YES.
1952
1953EXTRA_PACKAGES =
1954
1955# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for
1956# the generated LaTeX document. The header should contain everything until the
1957# first chapter. If it is left blank doxygen will generate a standard header. It
1958# is highly recommended to start with a default header using
1959# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty
1960# and then modify the file new_header.tex. See also section "Doxygen usage" for
1961# information on how to generate the default header that doxygen normally uses.
1962#
1963# Note: Only use a user-defined header if you know what you are doing!
1964# Note: The header is subject to change so you typically have to regenerate the
1965# default header when upgrading to a newer version of doxygen. The following
1966# commands have a special meaning inside the header (and footer): For a
1967# description of the possible markers and block names see the documentation.
1968# This tag requires that the tag GENERATE_LATEX is set to YES.
1969
1970LATEX_HEADER =
1971
1972# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for
1973# the generated LaTeX document. The footer should contain everything after the
1974# last chapter. If it is left blank doxygen will generate a standard footer. See
1975# LATEX_HEADER for more information on how to generate a default footer and what
1976# special commands can be used inside the footer. See also section "Doxygen
1977# usage" for information on how to generate the default footer that doxygen
1978# normally uses. Note: Only use a user-defined footer if you know what you are
1979# doing!
1980# This tag requires that the tag GENERATE_LATEX is set to YES.
1981
1982LATEX_FOOTER =
1983
1984# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
1985# LaTeX style sheets that are included after the standard style sheets created
1986# by doxygen. Using this option one can overrule certain style aspects. Doxygen
1987# will copy the style sheet files to the output directory.
1988# Note: The order of the extra style sheet files is of importance (e.g. the last
1989# style sheet in the list overrules the setting of the previous ones in the
1990# list).
1991# This tag requires that the tag GENERATE_LATEX is set to YES.
1992
1993LATEX_EXTRA_STYLESHEET =
1994
1995# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
1996# other source files which should be copied to the LATEX_OUTPUT output
1997# directory. Note that the files will be copied as-is; there are no commands or
1998# markers available.
1999# This tag requires that the tag GENERATE_LATEX is set to YES.
2000
2001LATEX_EXTRA_FILES =
2002
2003# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
2004# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
2005# contain links (just like the HTML output) instead of page references. This
2006# makes the output suitable for online browsing using a PDF viewer.
2007# The default value is: YES.
2008# This tag requires that the tag GENERATE_LATEX is set to YES.
2009
2010PDF_HYPERLINKS = YES
2011
2012# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
2013# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
2014# files. Set this option to YES, to get a higher quality PDF documentation.
2015#
2016# See also section LATEX_CMD_NAME for selecting the engine.
2017# The default value is: YES.
2018# This tag requires that the tag GENERATE_LATEX is set to YES.
2019
2020USE_PDFLATEX = YES
2021
2022# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
2023# command to the generated LaTeX files. This will instruct LaTeX to keep running
2024# if errors occur, instead of asking the user for help.
2025# The default value is: NO.
2026# This tag requires that the tag GENERATE_LATEX is set to YES.
2027
2028LATEX_BATCHMODE = NO
2029
2030# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
2031# index chapters (such as File Index, Compound Index, etc.) in the output.
2032# The default value is: NO.
2033# This tag requires that the tag GENERATE_LATEX is set to YES.
2034
2035LATEX_HIDE_INDICES = NO
2036
2037# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
2038# bibliography, e.g. plainnat, or ieeetr. See
2039# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
2040# The default value is: plain.
2041# This tag requires that the tag GENERATE_LATEX is set to YES.
2042
2043LATEX_BIB_STYLE = plain
2044
2045# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
2046# page will contain the date and time when the page was generated. Setting this
2047# to NO can help when comparing the output of multiple runs.
2048# The default value is: NO.
2049# This tag requires that the tag GENERATE_LATEX is set to YES.
2050
2051LATEX_TIMESTAMP = NO
2052
2053# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
2054# path from which the emoji images will be read. If a relative path is entered,
2055# it will be relative to the LATEX_OUTPUT directory. If left blank the
2056# LATEX_OUTPUT directory will be used.
2057# This tag requires that the tag GENERATE_LATEX is set to YES.
2058
2059LATEX_EMOJI_DIRECTORY =
2060
2061#---------------------------------------------------------------------------
2062# Configuration options related to the RTF output
2063#---------------------------------------------------------------------------
2064
2065# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
2066# RTF output is optimized for Word 97 and may not look too pretty with other RTF
2067# readers/editors.
2068# The default value is: NO.
2069
2070GENERATE_RTF = NO
2071
2072# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
2073# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
2074# it.
2075# The default directory is: rtf.
2076# This tag requires that the tag GENERATE_RTF is set to YES.
2077
2078RTF_OUTPUT = rtf
2079
2080# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
2081# documents. This may be useful for small projects and may help to save some
2082# trees in general.
2083# The default value is: NO.
2084# This tag requires that the tag GENERATE_RTF is set to YES.
2085
2086COMPACT_RTF = NO
2087
2088# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
2089# contain hyperlink fields. The RTF file will contain links (just like the HTML
2090# output) instead of page references. This makes the output suitable for online
2091# browsing using Word or some other Word compatible readers that support those
2092# fields.
2093#
2094# Note: WordPad (write) and others do not support links.
2095# The default value is: NO.
2096# This tag requires that the tag GENERATE_RTF is set to YES.
2097
2098RTF_HYPERLINKS = NO
2099
2100# Load stylesheet definitions from file. Syntax is similar to doxygen's
2101# configuration file, i.e. a series of assignments. You only have to provide
2102# replacements, missing definitions are set to their default value.
2103#
2104# See also section "Doxygen usage" for information on how to generate the
2105# default style sheet that doxygen normally uses.
2106# This tag requires that the tag GENERATE_RTF is set to YES.
2107
2108RTF_STYLESHEET_FILE =
2109
2110# Set optional variables used in the generation of an RTF document. Syntax is
2111# similar to doxygen's configuration file. A template extensions file can be
2112# generated using doxygen -e rtf extensionFile.
2113# This tag requires that the tag GENERATE_RTF is set to YES.
2114
2115RTF_EXTENSIONS_FILE =
2116
2117#---------------------------------------------------------------------------
2118# Configuration options related to the man page output
2119#---------------------------------------------------------------------------
2120
2121# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
2122# classes and files.
2123# The default value is: NO.
2124
2125GENERATE_MAN = NO
2126
2127# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
2128# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
2129# it. A directory man3 will be created inside the directory specified by
2130# MAN_OUTPUT.
2131# The default directory is: man.
2132# This tag requires that the tag GENERATE_MAN is set to YES.
2133
2134MAN_OUTPUT = man
2135
2136# The MAN_EXTENSION tag determines the extension that is added to the generated
2137# man pages. In case the manual section does not start with a number, the number
2138# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
2139# optional.
2140# The default value is: .3.
2141# This tag requires that the tag GENERATE_MAN is set to YES.
2142
2143MAN_EXTENSION = .3
2144
2145# The MAN_SUBDIR tag determines the name of the directory created within
2146# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
2147# MAN_EXTENSION with the initial . removed.
2148# This tag requires that the tag GENERATE_MAN is set to YES.
2149
2150MAN_SUBDIR =
2151
2152# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
2153# will generate one additional man file for each entity documented in the real
2154# man page(s). These additional files only source the real man page, but without
2155# them the man command would be unable to find the correct page.
2156# The default value is: NO.
2157# This tag requires that the tag GENERATE_MAN is set to YES.
2158
2159MAN_LINKS = NO
2160
2161#---------------------------------------------------------------------------
2162# Configuration options related to the XML output
2163#---------------------------------------------------------------------------
2164
2165# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
2166# captures the structure of the code including all documentation.
2167# The default value is: NO.
2168
2169GENERATE_XML = NO
2170
2171# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
2172# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
2173# it.
2174# The default directory is: xml.
2175# This tag requires that the tag GENERATE_XML is set to YES.
2176
2177XML_OUTPUT = xml
2178
2179# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
2180# listings (including syntax highlighting and cross-referencing information) to
2181# the XML output. Note that enabling this will significantly increase the size
2182# of the XML output.
2183# The default value is: YES.
2184# This tag requires that the tag GENERATE_XML is set to YES.
2185
2186XML_PROGRAMLISTING = YES
2187
2188# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
2189# namespace members in file scope as well, matching the HTML output.
2190# The default value is: NO.
2191# This tag requires that the tag GENERATE_XML is set to YES.
2192
2193XML_NS_MEMB_FILE_SCOPE = NO
2194
2195#---------------------------------------------------------------------------
2196# Configuration options related to the DOCBOOK output
2197#---------------------------------------------------------------------------
2198
2199# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
2200# that can be used to generate PDF.
2201# The default value is: NO.
2202
2203GENERATE_DOCBOOK = NO
2204
2205# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
2206# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
2207# front of it.
2208# The default directory is: docbook.
2209# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
2210
2211DOCBOOK_OUTPUT = docbook
2212
2213#---------------------------------------------------------------------------
2214# Configuration options for the AutoGen Definitions output
2215#---------------------------------------------------------------------------
2216
2217# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
2218# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
2219# the structure of the code including all documentation. Note that this feature
2220# is still experimental and incomplete at the moment.
2221# The default value is: NO.
2222
2223GENERATE_AUTOGEN_DEF = NO
2224
2225#---------------------------------------------------------------------------
2226# Configuration options related to the Perl module output
2227#---------------------------------------------------------------------------
2228
2229# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
2230# file that captures the structure of the code including all documentation.
2231#
2232# Note that this feature is still experimental and incomplete at the moment.
2233# The default value is: NO.
2234
2235GENERATE_PERLMOD = NO
2236
2237# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
2238# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
2239# output from the Perl module output.
2240# The default value is: NO.
2241# This tag requires that the tag GENERATE_PERLMOD is set to YES.
2242
2243PERLMOD_LATEX = NO
2244
2245# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
2246# formatted so it can be parsed by a human reader. This is useful if you want to
2247# understand what is going on. On the other hand, if this tag is set to NO, the
2248# size of the Perl module output will be much smaller and Perl will parse it
2249# just the same.
2250# The default value is: YES.
2251# This tag requires that the tag GENERATE_PERLMOD is set to YES.
2252
2253PERLMOD_PRETTY = YES
2254
2255# The names of the make variables in the generated doxyrules.make file are
2256# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
2257# so different doxyrules.make files included by the same Makefile don't
2258# overwrite each other's variables.
2259# This tag requires that the tag GENERATE_PERLMOD is set to YES.
2260
2261PERLMOD_MAKEVAR_PREFIX =
2262
2263#---------------------------------------------------------------------------
2264# Configuration options related to the preprocessor
2265#---------------------------------------------------------------------------
2266
2267# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
2268# C-preprocessor directives found in the sources and include files.
2269# The default value is: YES.
2270
2271ENABLE_PREPROCESSING = YES
2272
2273# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
2274# in the source code. If set to NO, only conditional compilation will be
2275# performed. Macro expansion can be done in a controlled way by setting
2276# EXPAND_ONLY_PREDEF to YES.
2277# The default value is: NO.
2278# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2279
2280MACRO_EXPANSION = NO
2281
2282# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
2283# the macro expansion is limited to the macros specified with the PREDEFINED and
2284# EXPAND_AS_DEFINED tags.
2285# The default value is: NO.
2286# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2287
2288EXPAND_ONLY_PREDEF = NO
2289
2290# If the SEARCH_INCLUDES tag is set to YES, the include files in the
2291# INCLUDE_PATH will be searched if a #include is found.
2292# The default value is: YES.
2293# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2294
2295SEARCH_INCLUDES = YES
2296
2297# The INCLUDE_PATH tag can be used to specify one or more directories that
2298# contain include files that are not input files but should be processed by the
2299# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of
2300# RECURSIVE has no effect here.
2301# This tag requires that the tag SEARCH_INCLUDES is set to YES.
2302
2303INCLUDE_PATH =
2304
2305# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
2306# patterns (like *.h and *.hpp) to filter out the header-files in the
2307# directories. If left blank, the patterns specified with FILE_PATTERNS will be
2308# used.
2309# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2310
2311INCLUDE_FILE_PATTERNS =
2312
2313# The PREDEFINED tag can be used to specify one or more macro names that are
2314# defined before the preprocessor is started (similar to the -D option of e.g.
2315# gcc). The argument of the tag is a list of macros of the form: name or
2316# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
2317# is assumed. To prevent a macro definition from being undefined via #undef or
2318# recursively expanded use the := operator instead of the = operator.
2319# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2320
2321PREDEFINED =
2322
2323# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
2324# tag can be used to specify a list of macro names that should be expanded. The
2325# macro definition that is found in the sources will be used. Use the PREDEFINED
2326# tag if you want to use a different macro definition that overrules the
2327# definition found in the source code.
2328# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2329
2330EXPAND_AS_DEFINED =
2331
2332# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
2333# remove all references to function-like macros that are alone on a line, have
2334# an all uppercase name, and do not end with a semicolon. Such function macros
2335# are typically used for boiler-plate code, and will confuse the parser if not
2336# removed.
2337# The default value is: YES.
2338# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
2339
2340SKIP_FUNCTION_MACROS = YES
2341
2342#---------------------------------------------------------------------------
2343# Configuration options related to external references
2344#---------------------------------------------------------------------------
2345
2346# The TAGFILES tag can be used to specify one or more tag files. For each tag
2347# file the location of the external documentation should be added. The format of
2348# a tag file without this location is as follows:
2349# TAGFILES = file1 file2 ...
2350# Adding location for the tag files is done as follows:
2351# TAGFILES = file1=loc1 "file2 = loc2" ...
2352# where loc1 and loc2 can be relative or absolute paths or URLs. See the
2353# section "Linking to external documentation" for more information about the use
2354# of tag files.
2355# Note: Each tag file must have a unique name (where the name does NOT include
2356# the path). If a tag file is not located in the directory in which doxygen is
2357# run, you must also specify the path to the tagfile here.
2358
2359TAGFILES =
2360
2361# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
2362# tag file that is based on the input files it reads. See section "Linking to
2363# external documentation" for more information about the usage of tag files.
2364
2365GENERATE_TAGFILE =
2366
2367# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
2368# the class index. If set to NO, only the inherited external classes will be
2369# listed.
2370# The default value is: NO.
2371
2372ALLEXTERNALS = NO
2373
2374# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
2375# in the modules index. If set to NO, only the current project's groups will be
2376# listed.
2377# The default value is: YES.
2378
2379EXTERNAL_GROUPS = YES
2380
2381# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
2382# the related pages index. If set to NO, only the current project's pages will
2383# be listed.
2384# The default value is: YES.
2385
2386EXTERNAL_PAGES = YES
2387
2388#---------------------------------------------------------------------------
2389# Configuration options related to the dot tool
2390#---------------------------------------------------------------------------
2391
2392# You can include diagrams made with dia in doxygen documentation. Doxygen will
2393# then run dia to produce the diagram and insert it in the documentation. The
2394# DIA_PATH tag allows you to specify the directory where the dia binary resides.
2395# If left empty dia is assumed to be found in the default search path.
2396
2397DIA_PATH =
2398
2399# If set to YES the inheritance and collaboration graphs will hide inheritance
2400# and usage relations if the target is undocumented or is not a class.
2401# The default value is: YES.
2402
2403HIDE_UNDOC_RELATIONS = YES
2404
2405# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
2406# available from the path. This tool is part of Graphviz (see:
2407# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
2408# Bell Labs. The other options in this section have no effect if this option is
2409# set to NO
2410# The default value is: NO.
2411
2412HAVE_DOT = NO
2413
2414# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
2415# to run in parallel. When set to 0 doxygen will base this on the number of
2416# processors available in the system. You can set it explicitly to a value
2417# larger than 0 to get control over the balance between CPU load and processing
2418# speed.
2419# Minimum value: 0, maximum value: 32, default value: 0.
2420# This tag requires that the tag HAVE_DOT is set to YES.
2421
2422DOT_NUM_THREADS = 0
2423
2424# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of
2425# subgraphs. When you want a differently looking font in the dot files that
2426# doxygen generates you can specify fontname, fontcolor and fontsize attributes.
2427# For details please see <a href=https://graphviz.org/doc/info/attrs.html>Node,
2428# Edge and Graph Attributes specification</a> You need to make sure dot is able
2429# to find the font, which can be done by putting it in a standard location or by
2430# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
2431# directory containing the font. Default graphviz fontsize is 14.
2432# The default value is: fontname=Helvetica,fontsize=10.
2433# This tag requires that the tag HAVE_DOT is set to YES.
2434
2435DOT_COMMON_ATTR = "fontname=FreeSans.ttf,fontsize=10"
2436
2437# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can
2438# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. <a
2439# href=https://graphviz.org/doc/info/arrows.html>Complete documentation about
2440# arrows shapes.</a>
2441# The default value is: labelfontname=Helvetica,labelfontsize=10.
2442# This tag requires that the tag HAVE_DOT is set to YES.
2443
2444DOT_EDGE_ATTR = "labelfontname=FreeSans.ttf,labelfontsize=10"
2445
2446# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes
2447# around nodes set 'shape=plain' or 'shape=plaintext' <a
2448# href=https://www.graphviz.org/doc/info/shapes.html>Shapes specification</a>
2449# The default value is: shape=box,height=0.2,width=0.4.
2450# This tag requires that the tag HAVE_DOT is set to YES.
2451
2452DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
2453
2454# You can set the path where dot can find font specified with fontname in
2455# DOT_COMMON_ATTR and others dot attributes.
2456# This tag requires that the tag HAVE_DOT is set to YES.
2457
2458DOT_FONTPATH =
2459
2460# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
2461# graph for each documented class showing the direct and indirect inheritance
2462# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
2463# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
2464# to TEXT the direct and indirect inheritance relations will be shown as texts /
2465# links.
2466# Possible values are: NO, YES, TEXT and GRAPH.
2467# The default value is: YES.
2468
2469CLASS_GRAPH = YES
2470
2471# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
2472# graph for each documented class showing the direct and indirect implementation
2473# dependencies (inheritance, containment, and class references variables) of the
2474# class with other documented classes.
2475# The default value is: YES.
2476# This tag requires that the tag HAVE_DOT is set to YES.
2477
2478COLLABORATION_GRAPH = YES
2479
2480# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
2481# groups, showing the direct groups dependencies. See also the chapter Grouping
2482# in the manual.
2483# The default value is: YES.
2484# This tag requires that the tag HAVE_DOT is set to YES.
2485
2486GROUP_GRAPHS = YES
2487
2488# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
2489# collaboration diagrams in a style similar to the OMG's Unified Modeling
2490# Language.
2491# The default value is: NO.
2492# This tag requires that the tag HAVE_DOT is set to YES.
2493
2494UML_LOOK = NO
2495
2496# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
2497# class node. If there are many fields or methods and many nodes the graph may
2498# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
2499# number of items for each type to make the size more manageable. Set this to 0
2500# for no limit. Note that the threshold may be exceeded by 50% before the limit
2501# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
2502# but if the number exceeds 15, the total amount of fields shown is limited to
2503# 10.
2504# Minimum value: 0, maximum value: 100, default value: 10.
2505# This tag requires that the tag UML_LOOK is set to YES.
2506
2507UML_LIMIT_NUM_FIELDS = 10
2508
2509# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
2510# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
2511# tag is set to YES, doxygen will add type and arguments for attributes and
2512# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
2513# will not generate fields with class member information in the UML graphs. The
2514# class diagrams will look similar to the default class diagrams but using UML
2515# notation for the relationships.
2516# Possible values are: NO, YES and NONE.
2517# The default value is: NO.
2518# This tag requires that the tag UML_LOOK is set to YES.
2519
2520DOT_UML_DETAILS = NO
2521
2522# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
2523# to display on a single line. If the actual line length exceeds this threshold
2524# significantly it will wrapped across multiple lines. Some heuristics are apply
2525# to avoid ugly line breaks.
2526# Minimum value: 0, maximum value: 1000, default value: 17.
2527# This tag requires that the tag HAVE_DOT is set to YES.
2528
2529DOT_WRAP_THRESHOLD = 17
2530
2531# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
2532# collaboration graphs will show the relations between templates and their
2533# instances.
2534# The default value is: NO.
2535# This tag requires that the tag HAVE_DOT is set to YES.
2536
2537TEMPLATE_RELATIONS = NO
2538
2539# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
2540# YES then doxygen will generate a graph for each documented file showing the
2541# direct and indirect include dependencies of the file with other documented
2542# files.
2543# The default value is: YES.
2544# This tag requires that the tag HAVE_DOT is set to YES.
2545
2546INCLUDE_GRAPH = YES
2547
2548# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
2549# set to YES then doxygen will generate a graph for each documented file showing
2550# the direct and indirect include dependencies of the file with other documented
2551# files.
2552# The default value is: YES.
2553# This tag requires that the tag HAVE_DOT is set to YES.
2554
2555INCLUDED_BY_GRAPH = YES
2556
2557# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
2558# dependency graph for every global function or class method.
2559#
2560# Note that enabling this option will significantly increase the time of a run.
2561# So in most cases it will be better to enable call graphs for selected
2562# functions only using the \callgraph command. Disabling a call graph can be
2563# accomplished by means of the command \hidecallgraph.
2564# The default value is: NO.
2565# This tag requires that the tag HAVE_DOT is set to YES.
2566
2567CALL_GRAPH = NO
2568
2569# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
2570# dependency graph for every global function or class method.
2571#
2572# Note that enabling this option will significantly increase the time of a run.
2573# So in most cases it will be better to enable caller graphs for selected
2574# functions only using the \callergraph command. Disabling a caller graph can be
2575# accomplished by means of the command \hidecallergraph.
2576# The default value is: NO.
2577# This tag requires that the tag HAVE_DOT is set to YES.
2578
2579CALLER_GRAPH = NO
2580
2581# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
2582# hierarchy of all classes instead of a textual one.
2583# The default value is: YES.
2584# This tag requires that the tag HAVE_DOT is set to YES.
2585
2586GRAPHICAL_HIERARCHY = YES
2587
2588# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
2589# dependencies a directory has on other directories in a graphical way. The
2590# dependency relations are determined by the #include relations between the
2591# files in the directories.
2592# The default value is: YES.
2593# This tag requires that the tag HAVE_DOT is set to YES.
2594
2595DIRECTORY_GRAPH = YES
2596
2597# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels
2598# of child directories generated in directory dependency graphs by dot.
2599# Minimum value: 1, maximum value: 25, default value: 1.
2600# This tag requires that the tag DIRECTORY_GRAPH is set to YES.
2601
2602DIR_GRAPH_MAX_DEPTH = 1
2603
2604# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
2605# generated by dot. For an explanation of the image formats see the section
2606# output formats in the documentation of the dot tool (Graphviz (see:
2607# http://www.graphviz.org/)).
2608# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
2609# to make the SVG files visible in IE 9+ (other browsers do not have this
2610# requirement).
2611# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
2612# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
2613# png:gdiplus:gdiplus.
2614# The default value is: png.
2615# This tag requires that the tag HAVE_DOT is set to YES.
2616
2617DOT_IMAGE_FORMAT = png
2618
2619# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
2620# enable generation of interactive SVG images that allow zooming and panning.
2621#
2622# Note that this requires a modern browser other than Internet Explorer. Tested
2623# and working are Firefox, Chrome, Safari, and Opera.
2624# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
2625# the SVG files visible. Older versions of IE do not have SVG support.
2626# The default value is: NO.
2627# This tag requires that the tag HAVE_DOT is set to YES.
2628
2629INTERACTIVE_SVG = NO
2630
2631# The DOT_PATH tag can be used to specify the path where the dot tool can be
2632# found. If left blank, it is assumed the dot tool can be found in the path.
2633# This tag requires that the tag HAVE_DOT is set to YES.
2634
2635DOT_PATH =
2636
2637# The DOTFILE_DIRS tag can be used to specify one or more directories that
2638# contain dot files that are included in the documentation (see the \dotfile
2639# command).
2640# This tag requires that the tag HAVE_DOT is set to YES.
2641
2642DOTFILE_DIRS =
2643
2644# The MSCFILE_DIRS tag can be used to specify one or more directories that
2645# contain msc files that are included in the documentation (see the \mscfile
2646# command).
2647
2648MSCFILE_DIRS =
2649
2650# The DIAFILE_DIRS tag can be used to specify one or more directories that
2651# contain dia files that are included in the documentation (see the \diafile
2652# command).
2653
2654DIAFILE_DIRS =
2655
2656# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
2657# path where java can find the plantuml.jar file or to the filename of jar file
2658# to be used. If left blank, it is assumed PlantUML is not used or called during
2659# a preprocessing step. Doxygen will generate a warning when it encounters a
2660# \startuml command in this case and will not generate output for the diagram.
2661
2662PLANTUML_JAR_PATH =
2663
2664# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
2665# configuration file for plantuml.
2666
2667PLANTUML_CFG_FILE =
2668
2669# When using plantuml, the specified paths are searched for files specified by
2670# the !include statement in a plantuml block.
2671
2672PLANTUML_INCLUDE_PATH =
2673
2674# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
2675# that will be shown in the graph. If the number of nodes in a graph becomes
2676# larger than this value, doxygen will truncate the graph, which is visualized
2677# by representing a node as a red box. Note that doxygen if the number of direct
2678# children of the root node in a graph is already larger than
2679# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
2680# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
2681# Minimum value: 0, maximum value: 10000, default value: 50.
2682# This tag requires that the tag HAVE_DOT is set to YES.
2683
2684DOT_GRAPH_MAX_NODES = 50
2685
2686# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
2687# generated by dot. A depth value of 3 means that only nodes reachable from the
2688# root by following a path via at most 3 edges will be shown. Nodes that lay
2689# further from the root node will be omitted. Note that setting this option to 1
2690# or 2 may greatly reduce the computation time needed for large code bases. Also
2691# note that the size of a graph can be further restricted by
2692# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
2693# Minimum value: 0, maximum value: 1000, default value: 0.
2694# This tag requires that the tag HAVE_DOT is set to YES.
2695
2696MAX_DOT_GRAPH_DEPTH = 0
2697
2698# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
2699# files in one run (i.e. multiple -o and -T options on the command line). This
2700# makes dot run faster, but since only newer versions of dot (>1.8.10) support
2701# this, this feature is disabled by default.
2702# The default value is: NO.
2703# This tag requires that the tag HAVE_DOT is set to YES.
2704
2705DOT_MULTI_TARGETS = YES
2706
2707# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
2708# explaining the meaning of the various boxes and arrows in the dot generated
2709# graphs.
2710# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
2711# graphical representation for inheritance and collaboration diagrams is used.
2712# The default value is: YES.
2713# This tag requires that the tag HAVE_DOT is set to YES.
2714
2715GENERATE_LEGEND = YES
2716
2717# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
2718# files that are used to generate the various graphs.
2719#
2720# Note: This setting is not only used for dot files but also for msc temporary
2721# files.
2722# The default value is: YES.
2723
2724DOT_CLEANUP = YES
diff --git a/contrib/SDL-3.2.8/src/hidapi/doxygen/main_page.md b/contrib/SDL-3.2.8/src/hidapi/doxygen/main_page.md
new file mode 100644
index 0000000..ff11e9a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/doxygen/main_page.md
@@ -0,0 +1,13 @@
1# HIDAPI Doxygen output
2
3This site is dedicated to hosting an [API reference for the HIDAPI library](#API).
4
5For general information, see the [source repository](https://github.com/libusb/hidapi#readme).
6
7There are also build instructions hosted on github:
8
9- [Building from source](https://github.com/libusb/hidapi/blob/master/BUILD.md)
10- [Using CMake](https://github.com/libusb/hidapi/blob/master/BUILD.cmake.md)
11- [Using Autotools (deprecated)](https://github.com/libusb/hidapi/blob/master/BUILD.autotools.md)
12
13\example test.c contains a basic example usage of the HIDAPI library.
diff --git a/contrib/SDL-3.2.8/src/hidapi/hidapi/hidapi.h b/contrib/SDL-3.2.8/src/hidapi/hidapi/hidapi.h
new file mode 100644
index 0000000..0e75f0d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/hidapi/hidapi.h
@@ -0,0 +1,634 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Copyright 2023, All Rights Reserved.
11
12 At the discretion of the user of this library,
13 this software may be licensed under the terms of the
14 GNU General Public License v3, a BSD-Style license, or the
15 original HIDAPI license as outlined in the LICENSE.txt,
16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17 files located at the root of the source distribution.
18 These files may also be found in the public source
19 code repository located at:
20 https://github.com/libusb/hidapi .
21********************************************************/
22
23/** @file
24 * @defgroup API hidapi API
25 */
26
27#ifndef HIDAPI_H__
28#define HIDAPI_H__
29
30#include <wchar.h>
31
32/* #480: this is to be refactored properly for v1.0 */
33#ifdef _WIN32
34 #ifndef HID_API_NO_EXPORT_DEFINE
35 #define HID_API_EXPORT __declspec(dllexport)
36 #endif
37#endif
38#ifndef HID_API_EXPORT
39 #define HID_API_EXPORT /**< API export macro */
40#endif
41/* To be removed in v1.0 */
42#define HID_API_CALL /**< API call macro */
43
44#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/
45
46/** @brief Static/compile-time major version of the library.
47
48 @ingroup API
49*/
50#define HID_API_VERSION_MAJOR 0
51/** @brief Static/compile-time minor version of the library.
52
53 @ingroup API
54*/
55#define HID_API_VERSION_MINOR 14
56/** @brief Static/compile-time patch version of the library.
57
58 @ingroup API
59*/
60#define HID_API_VERSION_PATCH 0
61
62/* Helper macros */
63#define HID_API_AS_STR_IMPL(x) #x
64#define HID_API_AS_STR(x) HID_API_AS_STR_IMPL(x)
65#define HID_API_TO_VERSION_STR(v1, v2, v3) HID_API_AS_STR(v1.v2.v3)
66
67/** @brief Coverts a version as Major/Minor/Patch into a number:
68 <8 bit major><16 bit minor><8 bit patch>.
69
70 This macro was added in version 0.12.0.
71
72 Convenient function to be used for compile-time checks, like:
73 @code{.c}
74 #if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
75 @endcode
76
77 @ingroup API
78*/
79#define HID_API_MAKE_VERSION(mj, mn, p) (((mj) << 24) | ((mn) << 8) | (p))
80
81/** @brief Static/compile-time version of the library.
82
83 This macro was added in version 0.12.0.
84
85 @see @ref HID_API_MAKE_VERSION.
86
87 @ingroup API
88*/
89#define HID_API_VERSION HID_API_MAKE_VERSION(HID_API_VERSION_MAJOR, HID_API_VERSION_MINOR, HID_API_VERSION_PATCH)
90
91/** @brief Static/compile-time string version of the library.
92
93 @ingroup API
94*/
95#define HID_API_VERSION_STR HID_API_TO_VERSION_STR(HID_API_VERSION_MAJOR, HID_API_VERSION_MINOR, HID_API_VERSION_PATCH)
96
97/** @brief Maximum expected HID Report descriptor size in bytes.
98
99 Since version 0.13.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 13, 0)
100
101 @ingroup API
102*/
103#define HID_API_MAX_REPORT_DESCRIPTOR_SIZE 4096
104
105#ifdef __cplusplus
106extern "C" {
107#endif
108#ifndef DEFINED_HID_TYPES
109#define DEFINED_HID_TYPES
110 /** A structure to hold the version numbers. */
111 struct hid_api_version {
112 int major; /**< major version number */
113 int minor; /**< minor version number */
114 int patch; /**< patch version number */
115 };
116
117 struct hid_device_;
118 typedef struct hid_device_ hid_device; /**< opaque hidapi structure */
119
120 /** @brief HID underlying bus types.
121
122 @ingroup API
123 */
124 typedef enum {
125 /** Unknown bus type */
126 HID_API_BUS_UNKNOWN = 0x00,
127
128 /** USB bus
129 Specifications:
130 https://usb.org/hid */
131 HID_API_BUS_USB = 0x01,
132
133 /** Bluetooth or Bluetooth LE bus
134 Specifications:
135 https://www.bluetooth.com/specifications/specs/human-interface-device-profile-1-1-1/
136 https://www.bluetooth.com/specifications/specs/hid-service-1-0/
137 https://www.bluetooth.com/specifications/specs/hid-over-gatt-profile-1-0/ */
138 HID_API_BUS_BLUETOOTH = 0x02,
139
140 /** I2C bus
141 Specifications:
142 https://docs.microsoft.com/previous-versions/windows/hardware/design/dn642101(v=vs.85) */
143 HID_API_BUS_I2C = 0x03,
144
145 /** SPI bus
146 Specifications:
147 https://www.microsoft.com/download/details.aspx?id=103325 */
148 HID_API_BUS_SPI = 0x04,
149 } hid_bus_type;
150
151 /** hidapi info structure */
152 struct hid_device_info {
153 /** Platform-specific device path */
154 char *path;
155 /** Device Vendor ID */
156 unsigned short vendor_id;
157 /** Device Product ID */
158 unsigned short product_id;
159 /** Serial Number */
160 wchar_t *serial_number;
161 /** Device Release Number in binary-coded decimal,
162 also known as Device Version Number */
163 unsigned short release_number;
164 /** Manufacturer String */
165 wchar_t *manufacturer_string;
166 /** Product string */
167 wchar_t *product_string;
168 /** Usage Page for this Device/Interface
169 (Windows/Mac/hidraw only) */
170 unsigned short usage_page;
171 /** Usage for this Device/Interface
172 (Windows/Mac/hidraw only) */
173 unsigned short usage;
174 /** The USB interface which this logical device
175 represents.
176
177 Valid only if the device is a USB HID device.
178 Set to -1 in all other cases.
179 */
180 int interface_number;
181
182 /** Pointer to the next device */
183 struct hid_device_info *next;
184
185 /** Underlying bus type
186 Since version 0.13.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 13, 0)
187 */
188 hid_bus_type bus_type;
189
190 /** Additional information about the USB interface.
191 (libusb only) */
192 int interface_class;
193 int interface_subclass;
194 int interface_protocol;
195 };
196
197#endif /* DEFINED_HID_TYPES */
198
199
200 /** @brief Initialize the HIDAPI library.
201
202 This function initializes the HIDAPI library. Calling it is not
203 strictly necessary, as it will be called automatically by
204 hid_enumerate() and any of the hid_open_*() functions if it is
205 needed. This function should be called at the beginning of
206 execution however, if there is a chance of HIDAPI handles
207 being opened by different threads simultaneously.
208
209 @ingroup API
210
211 @returns
212 This function returns 0 on success and -1 on error.
213 Call hid_error(NULL) to get the failure reason.
214 */
215 int HID_API_EXPORT HID_API_CALL hid_init(void);
216
217 /** @brief Finalize the HIDAPI library.
218
219 This function frees all of the static data associated with
220 HIDAPI. It should be called at the end of execution to avoid
221 memory leaks.
222
223 @ingroup API
224
225 @returns
226 This function returns 0 on success and -1 on error.
227 */
228 int HID_API_EXPORT HID_API_CALL hid_exit(void);
229
230 /** @brief Enumerate the HID Devices.
231
232 This function returns a linked list of all the HID devices
233 attached to the system which match vendor_id and product_id.
234 If @p vendor_id is set to 0 then any vendor matches.
235 If @p product_id is set to 0 then any product matches.
236 If @p vendor_id and @p product_id are both set to 0, then
237 all HID devices will be returned.
238
239 @ingroup API
240 @param vendor_id The Vendor ID (VID) of the types of device
241 to open.
242 @param product_id The Product ID (PID) of the types of
243 device to open.
244
245 @returns
246 This function returns a pointer to a linked list of type
247 struct #hid_device_info, containing information about the HID devices
248 attached to the system,
249 or NULL in the case of failure or if no HID devices present in the system.
250 Call hid_error(NULL) to get the failure reason.
251
252 @note The returned value by this function must to be freed by calling hid_free_enumeration(),
253 when not needed anymore.
254 */
255 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id);
256
257 /** @brief Free an enumeration Linked List
258
259 This function frees a linked list created by hid_enumerate().
260
261 @ingroup API
262 @param devs Pointer to a list of struct_device returned from
263 hid_enumerate().
264 */
265 void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs);
266
267 /** @brief Open a HID device using a Vendor ID (VID), Product ID
268 (PID) and optionally a serial number.
269
270 If @p serial_number is NULL, the first device with the
271 specified VID and PID is opened.
272
273 @ingroup API
274 @param vendor_id The Vendor ID (VID) of the device to open.
275 @param product_id The Product ID (PID) of the device to open.
276 @param serial_number The Serial Number of the device to open
277 (Optionally NULL).
278
279 @returns
280 This function returns a pointer to a #hid_device object on
281 success or NULL on failure.
282 Call hid_error(NULL) to get the failure reason.
283
284 @note The returned object must be freed by calling hid_close(),
285 when not needed anymore.
286 */
287 HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number);
288
289 /** @brief Open a HID device by its path name.
290
291 The path name be determined by calling hid_enumerate(), or a
292 platform-specific path name can be used (eg: /dev/hidraw0 on
293 Linux).
294
295 @ingroup API
296 @param path The path name of the device to open
297
298 @returns
299 This function returns a pointer to a #hid_device object on
300 success or NULL on failure.
301 Call hid_error(NULL) to get the failure reason.
302
303 @note The returned object must be freed by calling hid_close(),
304 when not needed anymore.
305 */
306 HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path);
307
308 /** @brief Write an Output report to a HID device.
309
310 The first byte of @p data[] must contain the Report ID. For
311 devices which only support a single report, this must be set
312 to 0x0. The remaining bytes contain the report data. Since
313 the Report ID is mandatory, calls to hid_write() will always
314 contain one more byte than the report contains. For example,
315 if a hid report is 16 bytes long, 17 bytes must be passed to
316 hid_write(), the Report ID (or 0x0, for devices with a
317 single report), followed by the report data (16 bytes). In
318 this example, the length passed in would be 17.
319
320 hid_write() will send the data on the first OUT endpoint, if
321 one exists. If it does not, it will send the data through
322 the Control Endpoint (Endpoint 0).
323
324 @ingroup API
325 @param dev A device handle returned from hid_open().
326 @param data The data to send, including the report number as
327 the first byte.
328 @param length The length in bytes of the data to send.
329
330 @returns
331 This function returns the actual number of bytes written and
332 -1 on error.
333 Call hid_error(dev) to get the failure reason.
334 */
335 int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length);
336
337 /** @brief Read an Input report from a HID device with timeout.
338
339 Input reports are returned
340 to the host through the INTERRUPT IN endpoint. The first byte will
341 contain the Report number if the device uses numbered reports.
342
343 @ingroup API
344 @param dev A device handle returned from hid_open().
345 @param data A buffer to put the read data into.
346 @param length The number of bytes to read. For devices with
347 multiple reports, make sure to read an extra byte for
348 the report number.
349 @param milliseconds timeout in milliseconds or -1 for blocking wait.
350
351 @returns
352 This function returns the actual number of bytes read and
353 -1 on error.
354 Call hid_error(dev) to get the failure reason.
355 If no packet was available to be read within
356 the timeout period, this function returns 0.
357 */
358 int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds);
359
360 /** @brief Read an Input report from a HID device.
361
362 Input reports are returned
363 to the host through the INTERRUPT IN endpoint. The first byte will
364 contain the Report number if the device uses numbered reports.
365
366 @ingroup API
367 @param dev A device handle returned from hid_open().
368 @param data A buffer to put the read data into.
369 @param length The number of bytes to read. For devices with
370 multiple reports, make sure to read an extra byte for
371 the report number.
372
373 @returns
374 This function returns the actual number of bytes read and
375 -1 on error.
376 Call hid_error(dev) to get the failure reason.
377 If no packet was available to be read and
378 the handle is in non-blocking mode, this function returns 0.
379 */
380 int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length);
381
382 /** @brief Set the device handle to be non-blocking.
383
384 In non-blocking mode calls to hid_read() will return
385 immediately with a value of 0 if there is no data to be
386 read. In blocking mode, hid_read() will wait (block) until
387 there is data to read before returning.
388
389 Nonblocking can be turned on and off at any time.
390
391 @ingroup API
392 @param dev A device handle returned from hid_open().
393 @param nonblock enable or not the nonblocking reads
394 - 1 to enable nonblocking
395 - 0 to disable nonblocking.
396
397 @returns
398 This function returns 0 on success and -1 on error.
399 Call hid_error(dev) to get the failure reason.
400 */
401 int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock);
402
403 /** @brief Send a Feature report to the device.
404
405 Feature reports are sent over the Control endpoint as a
406 Set_Report transfer. The first byte of @p data[] must
407 contain the Report ID. For devices which only support a
408 single report, this must be set to 0x0. The remaining bytes
409 contain the report data. Since the Report ID is mandatory,
410 calls to hid_send_feature_report() will always contain one
411 more byte than the report contains. For example, if a hid
412 report is 16 bytes long, 17 bytes must be passed to
413 hid_send_feature_report(): the Report ID (or 0x0, for
414 devices which do not use numbered reports), followed by the
415 report data (16 bytes). In this example, the length passed
416 in would be 17.
417
418 @ingroup API
419 @param dev A device handle returned from hid_open().
420 @param data The data to send, including the report number as
421 the first byte.
422 @param length The length in bytes of the data to send, including
423 the report number.
424
425 @returns
426 This function returns the actual number of bytes written and
427 -1 on error.
428 Call hid_error(dev) to get the failure reason.
429 */
430 int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length);
431
432 /** @brief Get a feature report from a HID device.
433
434 Set the first byte of @p data[] to the Report ID of the
435 report to be read. Make sure to allow space for this
436 extra byte in @p data[]. Upon return, the first byte will
437 still contain the Report ID, and the report data will
438 start in data[1].
439
440 @ingroup API
441 @param dev A device handle returned from hid_open().
442 @param data A buffer to put the read data into, including
443 the Report ID. Set the first byte of @p data[] to the
444 Report ID of the report to be read, or set it to zero
445 if your device does not use numbered reports.
446 @param length The number of bytes to read, including an
447 extra byte for the report ID. The buffer can be longer
448 than the actual report.
449
450 @returns
451 This function returns the number of bytes read plus
452 one for the report ID (which is still in the first
453 byte), or -1 on error.
454 Call hid_error(dev) to get the failure reason.
455 */
456 int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length);
457
458 /** @brief Get a input report from a HID device.
459
460 Since version 0.10.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 10, 0)
461
462 Set the first byte of @p data[] to the Report ID of the
463 report to be read. Make sure to allow space for this
464 extra byte in @p data[]. Upon return, the first byte will
465 still contain the Report ID, and the report data will
466 start in data[1].
467
468 @ingroup API
469 @param dev A device handle returned from hid_open().
470 @param data A buffer to put the read data into, including
471 the Report ID. Set the first byte of @p data[] to the
472 Report ID of the report to be read, or set it to zero
473 if your device does not use numbered reports.
474 @param length The number of bytes to read, including an
475 extra byte for the report ID. The buffer can be longer
476 than the actual report.
477
478 @returns
479 This function returns the number of bytes read plus
480 one for the report ID (which is still in the first
481 byte), or -1 on error.
482 Call hid_error(dev) to get the failure reason.
483 */
484 int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length);
485
486 /** @brief Close a HID device.
487
488 @ingroup API
489 @param dev A device handle returned from hid_open().
490 */
491 void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev);
492
493 /** @brief Get The Manufacturer String from a HID device.
494
495 @ingroup API
496 @param dev A device handle returned from hid_open().
497 @param string A wide string buffer to put the data into.
498 @param maxlen The length of the buffer in multiples of wchar_t.
499
500 @returns
501 This function returns 0 on success and -1 on error.
502 Call hid_error(dev) to get the failure reason.
503 */
504 int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen);
505
506 /** @brief Get The Product String from a HID device.
507
508 @ingroup API
509 @param dev A device handle returned from hid_open().
510 @param string A wide string buffer to put the data into.
511 @param maxlen The length of the buffer in multiples of wchar_t.
512
513 @returns
514 This function returns 0 on success and -1 on error.
515 Call hid_error(dev) to get the failure reason.
516 */
517 int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen);
518
519 /** @brief Get The Serial Number String from a HID device.
520
521 @ingroup API
522 @param dev A device handle returned from hid_open().
523 @param string A wide string buffer to put the data into.
524 @param maxlen The length of the buffer in multiples of wchar_t.
525
526 @returns
527 This function returns 0 on success and -1 on error.
528 Call hid_error(dev) to get the failure reason.
529 */
530 int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen);
531
532 /** @brief Get The struct #hid_device_info from a HID device.
533
534 Since version 0.13.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 13, 0)
535
536 @ingroup API
537 @param dev A device handle returned from hid_open().
538
539 @returns
540 This function returns a pointer to the struct #hid_device_info
541 for this hid_device, or NULL in the case of failure.
542 Call hid_error(dev) to get the failure reason.
543 This struct is valid until the device is closed with hid_close().
544
545 @note The returned object is owned by the @p dev, and SHOULD NOT be freed by the user.
546 */
547 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_get_device_info(hid_device *dev);
548
549 /** @brief Get a string from a HID device, based on its string index.
550
551 @ingroup API
552 @param dev A device handle returned from hid_open().
553 @param string_index The index of the string to get.
554 @param string A wide string buffer to put the data into.
555 @param maxlen The length of the buffer in multiples of wchar_t.
556
557 @returns
558 This function returns 0 on success and -1 on error.
559 Call hid_error(dev) to get the failure reason.
560 */
561 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen);
562
563 /** @brief Get a report descriptor from a HID device.
564
565 Since version 0.14.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 14, 0)
566
567 User has to provide a preallocated buffer where descriptor will be copied to.
568 The recommended size for preallocated buffer is @ref HID_API_MAX_REPORT_DESCRIPTOR_SIZE bytes.
569
570 @ingroup API
571 @param dev A device handle returned from hid_open().
572 @param buf The buffer to copy descriptor into.
573 @param buf_size The size of the buffer in bytes.
574
575 @returns
576 This function returns non-negative number of bytes actually copied, or -1 on error.
577 */
578 int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size);
579
580 /** @brief Get a string describing the last error which occurred.
581
582 This function is intended for logging/debugging purposes.
583
584 This function guarantees to never return NULL.
585 If there was no error in the last function call -
586 the returned string clearly indicates that.
587
588 Any HIDAPI function that can explicitly indicate an execution failure
589 (e.g. by an error code, or by returning NULL) - may set the error string,
590 to be returned by this function.
591
592 Strings returned from hid_error() must not be freed by the user,
593 i.e. owned by HIDAPI library.
594 Device-specific error string may remain allocated at most until hid_close() is called.
595 Global error string may remain allocated at most until hid_exit() is called.
596
597 @ingroup API
598 @param dev A device handle returned from hid_open(),
599 or NULL to get the last non-device-specific error
600 (e.g. for errors in hid_open() or hid_enumerate()).
601
602 @returns
603 A string describing the last error (if any).
604 */
605 HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev);
606
607 /** @brief Get a runtime version of the library.
608
609 This function is thread-safe.
610
611 @ingroup API
612
613 @returns
614 Pointer to statically allocated struct, that contains version.
615 */
616 HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void);
617
618
619 /** @brief Get a runtime version string of the library.
620
621 This function is thread-safe.
622
623 @ingroup API
624
625 @returns
626 Pointer to statically allocated string, that contains version string.
627 */
628 HID_API_EXPORT const char* HID_API_CALL hid_version_str(void);
629
630#ifdef __cplusplus
631}
632#endif
633
634#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/hidtest/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/hidtest/CMakeLists.txt
new file mode 100644
index 0000000..19c50e1
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/hidtest/CMakeLists.txt
@@ -0,0 +1,40 @@
1cmake_minimum_required(VERSION 3.1.3...3.25 FATAL_ERROR)
2project(hidtest C)
3
4if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
5 # hidtest is build as a standalone project
6
7 if(POLICY CMP0074)
8 # allow using hidapi_ROOT if CMake supports it
9 cmake_policy(SET CMP0074 NEW)
10 endif()
11
12 find_package(hidapi 0.12 REQUIRED)
13 message(STATUS "Using HIDAPI: ${hidapi_VERSION}")
14else()
15 # hidtest is built as part of the main HIDAPI build
16 message(STATUS "Building hidtest")
17endif()
18
19set(HIDAPI_HIDTEST_TARGETS)
20if(NOT WIN32 AND NOT APPLE AND CMAKE_SYSTEM_NAME MATCHES "Linux")
21 if(TARGET hidapi::hidraw)
22 add_executable(hidtest_hidraw test.c)
23 target_link_libraries(hidtest_hidraw hidapi::hidraw)
24 list(APPEND HIDAPI_HIDTEST_TARGETS hidtest_hidraw)
25 endif()
26 if(TARGET hidapi::libusb)
27 add_executable(hidtest_libusb test.c)
28 target_compile_definitions(hidtest_libusb PRIVATE USING_HIDAPI_LIBUSB)
29 target_link_libraries(hidtest_libusb hidapi::libusb)
30 list(APPEND HIDAPI_HIDTEST_TARGETS hidtest_libusb)
31 endif()
32else()
33 add_executable(hidtest test.c)
34 target_link_libraries(hidtest hidapi::hidapi)
35 list(APPEND HIDAPI_HIDTEST_TARGETS hidtest)
36endif()
37
38install(TARGETS ${HIDAPI_HIDTEST_TARGETS}
39 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
40)
diff --git a/contrib/SDL-3.2.8/src/hidapi/hidtest/Makefile.am b/contrib/SDL-3.2.8/src/hidapi/hidtest/Makefile.am
new file mode 100644
index 0000000..b601307
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/hidtest/Makefile.am
@@ -0,0 +1,28 @@
1AM_CPPFLAGS = -I$(top_srcdir)/hidapi/
2
3## Linux
4if OS_LINUX
5noinst_PROGRAMS = hidtest-libusb hidtest-hidraw
6
7hidtest_hidraw_SOURCES = test.c
8hidtest_hidraw_LDADD = $(top_builddir)/linux/libhidapi-hidraw.la
9
10hidtest_libusb_SOURCES = test.c
11hidtest_libusb_LDADD = $(top_builddir)/libusb/libhidapi-libusb.la
12else
13
14# Other OS's
15noinst_PROGRAMS = hidtest
16
17hidtest_SOURCES = test.c
18hidtest_LDADD = $(top_builddir)/$(backend)/libhidapi.la
19
20endif
21
22if OS_DARWIN
23AM_CPPFLAGS += -I$(top_srcdir)/mac/
24endif
25
26if OS_WINDOWS
27AM_CPPFLAGS += -I$(top_srcdir)/windows/
28endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/hidtest/test.c b/contrib/SDL-3.2.8/src/hidapi/hidtest/test.c
new file mode 100644
index 0000000..1eb6582
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/hidtest/test.c
@@ -0,0 +1,316 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Copyright 2022.
11
12 This contents of this file may be used by anyone
13 for any reason without any conditions and may be
14 used as a starting point for your own applications
15 which use HIDAPI.
16********************************************************/
17
18#include <stdio.h>
19#include <wchar.h>
20#include <string.h>
21#include <stdlib.h>
22
23#include <hidapi.h>
24
25// Headers needed for sleeping.
26#ifdef _WIN32
27 #include <windows.h>
28#else
29 #include <unistd.h>
30#endif
31
32// Fallback/example
33#ifndef HID_API_MAKE_VERSION
34#define HID_API_MAKE_VERSION(mj, mn, p) (((mj) << 24) | ((mn) << 8) | (p))
35#endif
36#ifndef HID_API_VERSION
37#define HID_API_VERSION HID_API_MAKE_VERSION(HID_API_VERSION_MAJOR, HID_API_VERSION_MINOR, HID_API_VERSION_PATCH)
38#endif
39
40//
41// Sample using platform-specific headers
42#if defined(__APPLE__) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
43#include <hidapi_darwin.h>
44#endif
45
46#if defined(_WIN32) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
47#include <hidapi_winapi.h>
48#endif
49
50#if defined(USING_HIDAPI_LIBUSB) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
51#include <hidapi_libusb.h>
52#endif
53//
54
55const char *hid_bus_name(hid_bus_type bus_type) {
56 static const char *const HidBusTypeName[] = {
57 "Unknown",
58 "USB",
59 "Bluetooth",
60 "I2C",
61 "SPI",
62 };
63
64 if ((int)bus_type < 0)
65 bus_type = HID_API_BUS_UNKNOWN;
66 if ((int)bus_type >= (int)(sizeof(HidBusTypeName) / sizeof(HidBusTypeName[0])))
67 bus_type = HID_API_BUS_UNKNOWN;
68
69 return HidBusTypeName[bus_type];
70}
71
72void print_device(struct hid_device_info *cur_dev) {
73 printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
74 printf("\n");
75 printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
76 printf(" Product: %ls\n", cur_dev->product_string);
77 printf(" Release: %hx\n", cur_dev->release_number);
78 printf(" Interface: %d\n", cur_dev->interface_number);
79 printf(" Usage (page): 0x%hx (0x%hx)\n", cur_dev->usage, cur_dev->usage_page);
80 printf(" Bus type: %u (%s)\n", (unsigned)cur_dev->bus_type, hid_bus_name(cur_dev->bus_type));
81 printf("\n");
82}
83
84void print_hid_report_descriptor_from_device(hid_device *device) {
85 unsigned char descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
86 int res = 0;
87
88 printf(" Report Descriptor: ");
89 res = hid_get_report_descriptor(device, descriptor, sizeof(descriptor));
90 if (res < 0) {
91 printf("error getting: %ls", hid_error(device));
92 }
93 else {
94 printf("(%d bytes)", res);
95 }
96 for (int i = 0; i < res; i++) {
97 if (i % 10 == 0) {
98 printf("\n");
99 }
100 printf("0x%02x, ", descriptor[i]);
101 }
102 printf("\n");
103}
104
105void print_hid_report_descriptor_from_path(const char *path) {
106 hid_device *device = hid_open_path(path);
107 if (device) {
108 print_hid_report_descriptor_from_device(device);
109 hid_close(device);
110 }
111 else {
112 printf(" Report Descriptor: Unable to open device by path\n");
113 }
114}
115
116void print_devices(struct hid_device_info *cur_dev) {
117 for (; cur_dev; cur_dev = cur_dev->next) {
118 print_device(cur_dev);
119 }
120}
121
122void print_devices_with_descriptor(struct hid_device_info *cur_dev) {
123 for (; cur_dev; cur_dev = cur_dev->next) {
124 print_device(cur_dev);
125 print_hid_report_descriptor_from_path(cur_dev->path);
126 }
127}
128
129int main(int argc, char* argv[])
130{
131 (void)argc;
132 (void)argv;
133
134 int res;
135 unsigned char buf[256];
136 #define MAX_STR 255
137 wchar_t wstr[MAX_STR];
138 hid_device *handle;
139 int i;
140
141 struct hid_device_info *devs;
142
143 printf("hidapi test/example tool. Compiled with hidapi version %s, runtime version %s.\n", HID_API_VERSION_STR, hid_version_str());
144 if (HID_API_VERSION == HID_API_MAKE_VERSION(hid_version()->major, hid_version()->minor, hid_version()->patch)) {
145 printf("Compile-time version matches runtime version of hidapi.\n\n");
146 }
147 else {
148 printf("Compile-time version is different than runtime version of hidapi.\n]n");
149 }
150
151 if (hid_init())
152 return -1;
153
154#if defined(__APPLE__) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
155 // To work properly needs to be called before hid_open/hid_open_path after hid_init.
156 // Best/recommended option - call it right after hid_init.
157 hid_darwin_set_open_exclusive(0);
158#endif
159
160 devs = hid_enumerate(0x0, 0x0);
161 print_devices_with_descriptor(devs);
162 hid_free_enumeration(devs);
163
164 // Set up the command buffer.
165 memset(buf,0x00,sizeof(buf));
166 buf[0] = 0x01;
167 buf[1] = 0x81;
168
169
170 // Open the device using the VID, PID,
171 // and optionally the Serial number.
172 ////handle = hid_open(0x4d8, 0x3f, L"12345");
173 handle = hid_open(0x4d8, 0x3f, NULL);
174 if (!handle) {
175 printf("unable to open device\n");
176 hid_exit();
177 return 1;
178 }
179
180 // Read the Manufacturer String
181 wstr[0] = 0x0000;
182 res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
183 if (res < 0)
184 printf("Unable to read manufacturer string\n");
185 printf("Manufacturer String: %ls\n", wstr);
186
187 // Read the Product String
188 wstr[0] = 0x0000;
189 res = hid_get_product_string(handle, wstr, MAX_STR);
190 if (res < 0)
191 printf("Unable to read product string\n");
192 printf("Product String: %ls\n", wstr);
193
194 // Read the Serial Number String
195 wstr[0] = 0x0000;
196 res = hid_get_serial_number_string(handle, wstr, MAX_STR);
197 if (res < 0)
198 printf("Unable to read serial number string\n");
199 printf("Serial Number String: (%d) %ls\n", wstr[0], wstr);
200
201 print_hid_report_descriptor_from_device(handle);
202
203 struct hid_device_info* info = hid_get_device_info(handle);
204 if (info == NULL) {
205 printf("Unable to get device info\n");
206 } else {
207 print_devices(info);
208 }
209
210 // Read Indexed String 1
211 wstr[0] = 0x0000;
212 res = hid_get_indexed_string(handle, 1, wstr, MAX_STR);
213 if (res < 0)
214 printf("Unable to read indexed string 1\n");
215 printf("Indexed String 1: %ls\n", wstr);
216
217 // Set the hid_read() function to be non-blocking.
218 hid_set_nonblocking(handle, 1);
219
220 // Try to read from the device. There should be no
221 // data here, but execution should not block.
222 res = hid_read(handle, buf, 17);
223
224 // Send a Feature Report to the device
225 buf[0] = 0x2;
226 buf[1] = 0xa0;
227 buf[2] = 0x0a;
228 buf[3] = 0x00;
229 buf[4] = 0x00;
230 res = hid_send_feature_report(handle, buf, 17);
231 if (res < 0) {
232 printf("Unable to send a feature report.\n");
233 }
234
235 memset(buf,0,sizeof(buf));
236
237 // Read a Feature Report from the device
238 buf[0] = 0x2;
239 res = hid_get_feature_report(handle, buf, sizeof(buf));
240 if (res < 0) {
241 printf("Unable to get a feature report: %ls\n", hid_error(handle));
242 }
243 else {
244 // Print out the returned buffer.
245 printf("Feature Report\n ");
246 for (i = 0; i < res; i++)
247 printf("%02x ", (unsigned int) buf[i]);
248 printf("\n");
249 }
250
251 memset(buf,0,sizeof(buf));
252
253 // Toggle LED (cmd 0x80). The first byte is the report number (0x1).
254 buf[0] = 0x1;
255 buf[1] = 0x80;
256 res = hid_write(handle, buf, 17);
257 if (res < 0) {
258 printf("Unable to write(): %ls\n", hid_error(handle));
259 }
260
261
262 // Request state (cmd 0x81). The first byte is the report number (0x1).
263 buf[0] = 0x1;
264 buf[1] = 0x81;
265 hid_write(handle, buf, 17);
266 if (res < 0) {
267 printf("Unable to write()/2: %ls\n", hid_error(handle));
268 }
269
270 // Read requested state. hid_read() has been set to be
271 // non-blocking by the call to hid_set_nonblocking() above.
272 // This loop demonstrates the non-blocking nature of hid_read().
273 res = 0;
274 i = 0;
275 while (res == 0) {
276 res = hid_read(handle, buf, sizeof(buf));
277 if (res == 0) {
278 printf("waiting...\n");
279 }
280 if (res < 0) {
281 printf("Unable to read(): %ls\n", hid_error(handle));
282 break;
283 }
284
285 i++;
286 if (i >= 10) { /* 10 tries by 500 ms - 5 seconds of waiting*/
287 printf("read() timeout\n");
288 break;
289 }
290
291#ifdef _WIN32
292 Sleep(500);
293#else
294 usleep(500*1000);
295#endif
296 }
297
298 if (res > 0) {
299 printf("Data read:\n ");
300 // Print out the returned buffer.
301 for (i = 0; i < res; i++)
302 printf("%02x ", (unsigned int) buf[i]);
303 printf("\n");
304 }
305
306 hid_close(handle);
307
308 /* Free static HIDAPI objects. */
309 hid_exit();
310
311#ifdef _WIN32
312 system("pause");
313#endif
314
315 return 0;
316}
diff --git a/contrib/SDL-3.2.8/src/hidapi/ios/hid.m b/contrib/SDL-3.2.8/src/hidapi/ios/hid.m
new file mode 100644
index 0000000..29e0782
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/ios/hid.m
@@ -0,0 +1,1038 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 2021 Valve Corporation
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#if defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS)
24
25#ifndef SDL_HIDAPI_DISABLED
26
27#include "../SDL_hidapi_c.h"
28
29#define hid_close PLATFORM_hid_close
30#define hid_device PLATFORM_hid_device
31#define hid_device_ PLATFORM_hid_device_
32#define hid_enumerate PLATFORM_hid_enumerate
33#define hid_error PLATFORM_hid_error
34#define hid_exit PLATFORM_hid_exit
35#define hid_free_enumeration PLATFORM_hid_free_enumeration
36#define hid_get_device_info PLATFORM_hid_get_device_info
37#define hid_get_feature_report PLATFORM_hid_get_feature_report
38#define hid_get_indexed_string PLATFORM_hid_get_indexed_string
39#define hid_get_input_report PLATFORM_hid_get_input_report
40#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string
41#define hid_get_product_string PLATFORM_hid_get_product_string
42#define hid_get_report_descriptor PLATFORM_hid_get_report_descriptor
43#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string
44#define hid_init PLATFORM_hid_init
45#define hid_open_path PLATFORM_hid_open_path
46#define hid_open PLATFORM_hid_open
47#define hid_read PLATFORM_hid_read
48#define hid_read_timeout PLATFORM_hid_read_timeout
49#define hid_send_feature_report PLATFORM_hid_send_feature_report
50#define hid_set_nonblocking PLATFORM_hid_set_nonblocking
51#define hid_version PLATFORM_hid_version
52#define hid_version_str PLATFORM_hid_version_str
53#define hid_write PLATFORM_hid_write
54
55#include <CoreBluetooth/CoreBluetooth.h>
56#include <QuartzCore/QuartzCore.h>
57#import <UIKit/UIKit.h>
58#import <mach/mach_time.h>
59#include <pthread.h>
60#include <sys/time.h>
61#include <unistd.h>
62#include "../hidapi/hidapi.h"
63
64#define VALVE_USB_VID 0x28DE
65#define D0G_BLE2_PID 0x1106
66
67typedef uint32_t uint32;
68typedef uint64_t uint64;
69
70// enables detailed NSLog logging of feature reports
71#define FEATURE_REPORT_LOGGING 0
72
73#define REPORT_SEGMENT_DATA_FLAG 0x80
74#define REPORT_SEGMENT_LAST_FLAG 0x40
75
76#define VALVE_SERVICE @"100F6C32-1735-4313-B402-38567131E5F3"
77
78// (READ/NOTIFICATIONS)
79#define VALVE_INPUT_CHAR @"100F6C33-1735-4313-B402-38567131E5F3"
80
81//  (READ/WRITE)
82#define VALVE_REPORT_CHAR @"100F6C34-1735-4313-B402-38567131E5F3"
83
84// TODO: create CBUUID's in __attribute__((constructor)) rather than doing [CBUUID UUIDWithString:...] everywhere
85
86#pragma pack(push,1)
87
88typedef struct
89{
90 uint8_t segmentHeader;
91 uint8_t featureReportMessageID;
92 uint8_t length;
93 uint8_t settingIdentifier;
94 union {
95 uint16_t usPayload;
96 uint32_t uPayload;
97 uint64_t ulPayload;
98 uint8_t ucPayload[15];
99 };
100} bluetoothSegment;
101
102typedef struct {
103 uint8_t id;
104 union {
105 bluetoothSegment segment;
106 struct {
107 uint8_t segmentHeader;
108 uint8_t featureReportMessageID;
109 uint8_t length;
110 uint8_t settingIdentifier;
111 union {
112 uint16_t usPayload;
113 uint32_t uPayload;
114 uint64_t ulPayload;
115 uint8_t ucPayload[15];
116 };
117 };
118 };
119} hidFeatureReport;
120
121#pragma pack(pop)
122
123size_t GetBluetoothSegmentSize(bluetoothSegment *segment)
124{
125 return segment->length + 3;
126}
127
128#define RingBuffer_cbElem 19
129#define RingBuffer_nElem 4096
130
131typedef struct {
132 int _first, _last;
133 uint8_t _data[ ( RingBuffer_nElem * RingBuffer_cbElem ) ];
134 pthread_mutex_t accessLock;
135} RingBuffer;
136
137static void RingBuffer_init( RingBuffer *this )
138{
139 this->_first = -1;
140 this->_last = 0;
141 pthread_mutex_init( &this->accessLock, 0 );
142}
143
144static bool RingBuffer_write( RingBuffer *this, const uint8_t *src )
145{
146 pthread_mutex_lock( &this->accessLock );
147 memcpy( &this->_data[ this->_last ], src, RingBuffer_cbElem );
148 if ( this->_first == -1 )
149 {
150 this->_first = this->_last;
151 }
152 this->_last = ( this->_last + RingBuffer_cbElem ) % (RingBuffer_nElem * RingBuffer_cbElem);
153 if ( this->_last == this->_first )
154 {
155 this->_first = ( this->_first + RingBuffer_cbElem ) % (RingBuffer_nElem * RingBuffer_cbElem);
156 pthread_mutex_unlock( &this->accessLock );
157 return false;
158 }
159 pthread_mutex_unlock( &this->accessLock );
160 return true;
161}
162
163static bool RingBuffer_read( RingBuffer *this, uint8_t *dst )
164{
165 pthread_mutex_lock( &this->accessLock );
166 if ( this->_first == -1 )
167 {
168 pthread_mutex_unlock( &this->accessLock );
169 return false;
170 }
171 memcpy( dst, &this->_data[ this->_first ], RingBuffer_cbElem );
172 this->_first = ( this->_first + RingBuffer_cbElem ) % (RingBuffer_nElem * RingBuffer_cbElem);
173 if ( this->_first == this->_last )
174 {
175 this->_first = -1;
176 }
177 pthread_mutex_unlock( &this->accessLock );
178 return true;
179}
180
181
182#pragma mark HIDBLEDevice Definition
183
184typedef enum
185{
186 BLEDeviceWaitState_None,
187 BLEDeviceWaitState_Waiting,
188 BLEDeviceWaitState_Complete,
189 BLEDeviceWaitState_Error
190} BLEDeviceWaitState;
191
192@interface HIDBLEDevice : NSObject <CBPeripheralDelegate>
193{
194 RingBuffer _inputReports;
195 uint8_t _featureReport[20];
196 BLEDeviceWaitState _waitStateForReadFeatureReport;
197 BLEDeviceWaitState _waitStateForWriteFeatureReport;
198}
199
200@property (nonatomic, readwrite) bool connected;
201@property (nonatomic, readwrite) bool ready;
202
203@property (nonatomic, strong) CBPeripheral *bleSteamController;
204@property (nonatomic, strong) CBCharacteristic *bleCharacteristicInput;
205@property (nonatomic, strong) CBCharacteristic *bleCharacteristicReport;
206
207- (id)initWithPeripheral:(CBPeripheral *)peripheral;
208
209@end
210
211
212@interface HIDBLEManager : NSObject <CBCentralManagerDelegate>
213
214@property (nonatomic) int nPendingScans;
215@property (nonatomic) int nPendingPairs;
216@property (nonatomic, strong) CBCentralManager *centralManager;
217@property (nonatomic, strong) NSMapTable<CBPeripheral *, HIDBLEDevice *> *deviceMap;
218@property (nonatomic, retain) dispatch_queue_t bleSerialQueue;
219
220+ (instancetype)sharedInstance;
221- (void)startScan:(int)duration;
222- (void)stopScan;
223- (int)updateConnectedSteamControllers:(BOOL) bForce;
224- (void)appWillResignActiveNotification:(NSNotification *)note;
225- (void)appDidBecomeActiveNotification:(NSNotification *)note;
226
227@end
228
229
230// singleton class - access using HIDBLEManager.sharedInstance
231@implementation HIDBLEManager
232
233+ (instancetype)sharedInstance
234{
235 static HIDBLEManager *sharedInstance = nil;
236 static dispatch_once_t onceToken;
237 dispatch_once(&onceToken, ^{
238 sharedInstance = [HIDBLEManager new];
239 sharedInstance.nPendingScans = 0;
240 sharedInstance.nPendingPairs = 0;
241
242 // Bluetooth is currently only used for Steam Controllers, so check that hint
243 // before initializing Bluetooth, which will prompt the user for permission.
244 if ( SDL_GetHintBoolean( SDL_HINT_JOYSTICK_HIDAPI_STEAM, false ) )
245 {
246 [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appWillResignActiveNotification:) name: UIApplicationWillResignActiveNotification object:nil];
247 [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appDidBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil];
248
249 // receive reports on a high-priority serial-queue. optionally put writes on the serial queue to avoid logical
250 // race conditions talking to the controller from multiple threads, although BLE fragmentation/assembly means
251 // that we can still screw this up.
252 // most importantly we need to consume reports at a high priority to avoid the OS thinking we aren't really
253 // listening to the BLE device, as iOS on slower devices may stop delivery of packets to the app WITHOUT ACTUALLY
254 // DISCONNECTING FROM THE DEVICE if we don't react quickly enough to their delivery.
255 // see also the error-handling states in the peripheral delegate to re-open the device if it gets closed
256 sharedInstance.bleSerialQueue = dispatch_queue_create( "com.valvesoftware.steamcontroller.ble", DISPATCH_QUEUE_SERIAL );
257 dispatch_set_target_queue( sharedInstance.bleSerialQueue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
258
259 // creating a CBCentralManager will always trigger a future centralManagerDidUpdateState:
260 // where any scanning gets started or connecting to existing peripherals happens, it's never already in a
261 // powered-on state for a newly launched application.
262 sharedInstance.centralManager = [[CBCentralManager alloc] initWithDelegate:sharedInstance queue:sharedInstance.bleSerialQueue];
263 }
264 sharedInstance.deviceMap = [[NSMapTable alloc] initWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableStrongMemory capacity:4];
265 });
266 return sharedInstance;
267}
268
269// called for NSNotification UIApplicationWillResignActiveNotification
270- (void)appWillResignActiveNotification:(NSNotification *)note
271{
272 // we'll get resign-active notification if pairing is happening.
273 if ( self.nPendingPairs > 0 )
274 return;
275
276 for ( CBPeripheral *peripheral in self.deviceMap )
277 {
278 HIDBLEDevice *steamController = [self.deviceMap objectForKey:peripheral];
279 if ( steamController )
280 {
281 steamController.connected = NO;
282 steamController.ready = NO;
283 [self.centralManager cancelPeripheralConnection:peripheral];
284 }
285 }
286 [self.deviceMap removeAllObjects];
287}
288
289// called for NSNotification UIApplicationDidBecomeActiveNotification
290// whenever the application comes back from being inactive, trigger a 20s pairing scan and reconnect
291// any devices that may have paired while we were inactive.
292- (void)appDidBecomeActiveNotification:(NSNotification *)note
293{
294 [self updateConnectedSteamControllers:true];
295 [self startScan:20];
296}
297
298- (int)updateConnectedSteamControllers:(BOOL) bForce
299{
300 static uint64_t s_unLastUpdateTick = 0;
301 static mach_timebase_info_data_t s_timebase_info;
302
303 if ( self.centralManager == nil )
304 {
305 return 0;
306 }
307
308 if (s_timebase_info.denom == 0)
309 {
310 mach_timebase_info( &s_timebase_info );
311 }
312
313 uint64_t ticksNow = mach_approximate_time();
314 if ( !bForce && ( ( (ticksNow - s_unLastUpdateTick) * s_timebase_info.numer ) / s_timebase_info.denom ) < (5ull * NSEC_PER_SEC) )
315 return (int)self.deviceMap.count;
316
317 // we can see previously connected BLE peripherals but can't connect until the CBCentralManager
318 // is fully powered up - only do work when we are in that state
319 if ( self.centralManager.state != CBManagerStatePoweredOn )
320 return (int)self.deviceMap.count;
321
322 // only update our last-check-time if we actually did work, otherwise there can be a long delay during initial power-up
323 s_unLastUpdateTick = mach_approximate_time();
324
325 // if a pair is in-flight, the central manager may still give it back via retrieveConnected... and
326 // cause the SDL layer to attempt to initialize it while some of its endpoints haven't yet been established
327 if ( self.nPendingPairs > 0 )
328 return (int)self.deviceMap.count;
329
330 NSArray<CBPeripheral *> *peripherals = [self.centralManager retrieveConnectedPeripheralsWithServices: @[ [CBUUID UUIDWithString:@"180A"]]];
331 for ( CBPeripheral *peripheral in peripherals )
332 {
333 // we already know this peripheral
334 if ( [self.deviceMap objectForKey: peripheral] != nil )
335 continue;
336
337 NSLog( @"connected peripheral: %@", peripheral );
338 if ( [peripheral.name hasPrefix:@"Steam"] )
339 {
340 self.nPendingPairs += 1;
341 HIDBLEDevice *steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral];
342 [self.deviceMap setObject:steamController forKey:peripheral];
343 [self.centralManager connectPeripheral:peripheral options:nil];
344 }
345 }
346
347 return (int)self.deviceMap.count;
348}
349
350// manual API for folks to start & stop scanning
351- (void)startScan:(int)duration
352{
353 if ( self.centralManager == nil )
354 {
355 return;
356 }
357
358 NSLog( @"BLE: requesting scan for %d seconds", duration );
359 @synchronized (self)
360 {
361 if ( _nPendingScans++ == 0 )
362 {
363 [self.centralManager scanForPeripheralsWithServices:nil options:nil];
364 }
365 }
366
367 if ( duration != 0 )
368 {
369 dispatch_after( dispatch_time( DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
370 [self stopScan];
371 });
372 }
373}
374
375- (void)stopScan
376{
377 if ( self.centralManager == nil )
378 {
379 return;
380 }
381
382 NSLog( @"BLE: stopping scan" );
383 @synchronized (self)
384 {
385 if ( --_nPendingScans <= 0 )
386 {
387 _nPendingScans = 0;
388 [self.centralManager stopScan];
389 }
390 }
391}
392
393
394#pragma mark CBCentralManagerDelegate Implementation
395
396// called whenever the BLE hardware state changes.
397- (void)centralManagerDidUpdateState:(CBCentralManager *)central
398{
399 switch ( central.state )
400 {
401 case CBManagerStatePoweredOn:
402 {
403 NSLog( @"CoreBluetooth BLE hardware is powered on and ready" );
404
405 // at startup, if we have no already attached peripherals, do a 20s scan for new unpaired devices,
406 // otherwise callers should occaisionally do additional scans. we don't want to continuously be
407 // scanning because it drains battery, causes other nearby people to have a hard time pairing their
408 // Steam Controllers, and may also trigger firmware weirdness when a device attempts to start
409 // the pairing sequence multiple times concurrently
410 if ( [self updateConnectedSteamControllers:false] == 0 )
411 {
412 // TODO: we could limit our scan to only peripherals supporting the SteamController service, but
413 // that service doesn't currently fit in the base advertising packet, we'd need to put it into an
414 // extended scan packet. Useful optimization downstream, but not currently necessary
415 // NSArray *services = @[[CBUUID UUIDWithString:VALVE_SERVICE]];
416 [self startScan:20];
417 }
418 break;
419 }
420
421 case CBManagerStatePoweredOff:
422 NSLog( @"CoreBluetooth BLE hardware is powered off" );
423 break;
424
425 case CBManagerStateUnauthorized:
426 NSLog( @"CoreBluetooth BLE state is unauthorized" );
427 break;
428
429 case CBManagerStateUnknown:
430 NSLog( @"CoreBluetooth BLE state is unknown" );
431 break;
432
433 case CBManagerStateUnsupported:
434 NSLog( @"CoreBluetooth BLE hardware is unsupported on this platform" );
435 break;
436
437 case CBManagerStateResetting:
438 NSLog( @"CoreBluetooth BLE manager is resetting" );
439 break;
440 }
441}
442
443- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
444{
445 HIDBLEDevice *steamController = [_deviceMap objectForKey:peripheral];
446 steamController.connected = YES;
447 self.nPendingPairs -= 1;
448}
449
450- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
451{
452 NSLog( @"Failed to connect: %@", error );
453 [_deviceMap removeObjectForKey:peripheral];
454 self.nPendingPairs -= 1;
455}
456
457- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
458{
459 NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
460 NSString *log = [NSString stringWithFormat:@"Found '%@'", localName];
461
462 if ( [localName hasPrefix:@"Steam"] )
463 {
464 NSLog( @"%@ : %@ - %@", log, peripheral, advertisementData );
465 self.nPendingPairs += 1;
466 HIDBLEDevice *steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral];
467 [self.deviceMap setObject:steamController forKey:peripheral];
468 [self.centralManager connectPeripheral:peripheral options:nil];
469 }
470}
471
472- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
473{
474 HIDBLEDevice *steamController = [self.deviceMap objectForKey:peripheral];
475 if ( steamController )
476 {
477 steamController.connected = NO;
478 steamController.ready = NO;
479 [self.deviceMap removeObjectForKey:peripheral];
480 }
481}
482
483@end
484
485
486// Core Bluetooth devices calling back on event boundaries of their run-loops. so annoying.
487static void process_pending_events(void)
488{
489 CFRunLoopRunResult res;
490 do
491 {
492 res = CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0.001, FALSE );
493 }
494 while( res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut );
495}
496
497@implementation HIDBLEDevice
498
499- (id)init
500{
501 if ( self = [super init] )
502 {
503 RingBuffer_init( &_inputReports );
504 self.bleSteamController = nil;
505 self.bleCharacteristicInput = nil;
506 self.bleCharacteristicReport = nil;
507 _connected = NO;
508 _ready = NO;
509 }
510 return self;
511}
512
513- (id)initWithPeripheral:(CBPeripheral *)peripheral
514{
515 if ( self = [super init] )
516 {
517 RingBuffer_init( &_inputReports );
518 _connected = NO;
519 _ready = NO;
520 self.bleSteamController = peripheral;
521 if ( peripheral )
522 {
523 peripheral.delegate = self;
524 }
525 self.bleCharacteristicInput = nil;
526 self.bleCharacteristicReport = nil;
527 }
528 return self;
529}
530
531- (void)setConnected:(bool)connected
532{
533 _connected = connected;
534 if ( _connected )
535 {
536 [_bleSteamController discoverServices:nil];
537 }
538 else
539 {
540 NSLog( @"Disconnected" );
541 }
542}
543
544- (size_t)read_input_report:(uint8_t *)dst
545{
546 if ( RingBuffer_read( &_inputReports, dst+1 ) )
547 {
548 *dst = 0x03;
549 return 20;
550 }
551 return 0;
552}
553
554- (int)send_report:(const uint8_t *)data length:(size_t)length
555{
556 [_bleSteamController writeValue:[NSData dataWithBytes:data length:length] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
557 return (int)length;
558}
559
560- (int)send_feature_report:(hidFeatureReport *)report
561{
562#if FEATURE_REPORT_LOGGING
563 uint8_t *reportBytes = (uint8_t *)report;
564
565 NSLog( @"HIDBLE:send_feature_report (%02zu/19) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", GetBluetoothSegmentSize( report->segment ),
566 reportBytes[1], reportBytes[2], reportBytes[3], reportBytes[4], reportBytes[5], reportBytes[6],
567 reportBytes[7], reportBytes[8], reportBytes[9], reportBytes[10], reportBytes[11], reportBytes[12],
568 reportBytes[13], reportBytes[14], reportBytes[15], reportBytes[16], reportBytes[17], reportBytes[18],
569 reportBytes[19] );
570#endif
571
572 int sendSize = (int)GetBluetoothSegmentSize( &report->segment );
573 if ( sendSize > 20 )
574 sendSize = 20;
575
576#if 1
577 // fire-and-forget - we are going to not wait for the response here because all Steam Controller BLE send_feature_report's are ignored,
578 // except errors.
579 [_bleSteamController writeValue:[NSData dataWithBytes:&report->segment length:sendSize] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
580
581 // pretend we received a result anybody cares about
582 return 19;
583
584#else
585 // this is technically the correct send_feature_report logic if you want to make sure it gets through and is
586 // acknowledged or errors out
587 _waitStateForWriteFeatureReport = BLEDeviceWaitState_Waiting;
588 [_bleSteamController writeValue:[NSData dataWithBytes:&report->segment length:sendSize
589 ] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
590
591 while ( _waitStateForWriteFeatureReport == BLEDeviceWaitState_Waiting )
592 {
593 process_pending_events();
594 }
595
596 if ( _waitStateForWriteFeatureReport == BLEDeviceWaitState_Error )
597 {
598 _waitStateForWriteFeatureReport = BLEDeviceWaitState_None;
599 return -1;
600 }
601
602 _waitStateForWriteFeatureReport = BLEDeviceWaitState_None;
603 return 19;
604#endif
605}
606
607- (int)get_feature_report:(uint8_t)feature into:(uint8_t *)buffer
608{
609 _waitStateForReadFeatureReport = BLEDeviceWaitState_Waiting;
610 [_bleSteamController readValueForCharacteristic:_bleCharacteristicReport];
611
612 while ( _waitStateForReadFeatureReport == BLEDeviceWaitState_Waiting )
613 process_pending_events();
614
615 if ( _waitStateForReadFeatureReport == BLEDeviceWaitState_Error )
616 {
617 _waitStateForReadFeatureReport = BLEDeviceWaitState_None;
618 return -1;
619 }
620
621 memcpy( buffer, _featureReport, sizeof(_featureReport) );
622
623 _waitStateForReadFeatureReport = BLEDeviceWaitState_None;
624
625#if FEATURE_REPORT_LOGGING
626 NSLog( @"HIDBLE:get_feature_report (19) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]",
627 buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6],
628 buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], buffer[12],
629 buffer[13], buffer[14], buffer[15], buffer[16], buffer[17], buffer[18],
630 buffer[19] );
631#endif
632
633 return 19;
634}
635
636#pragma mark CBPeripheralDelegate Implementation
637
638- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
639{
640 for (CBService *service in peripheral.services)
641 {
642 NSLog( @"Found Service: %@", service );
643 if ( [service.UUID isEqual:[CBUUID UUIDWithString:VALVE_SERVICE]] )
644 {
645 [peripheral discoverCharacteristics:nil forService:service];
646 }
647 }
648}
649
650- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
651{
652 // nothing yet needed here, enable for logging
653 if ( /* DISABLES CODE */ (0) )
654 {
655 for ( CBDescriptor *descriptor in characteristic.descriptors )
656 {
657 NSLog( @" - Descriptor '%@'", descriptor );
658 }
659 }
660}
661
662- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
663{
664 if ([service.UUID isEqual:[CBUUID UUIDWithString:VALVE_SERVICE]])
665 {
666 for (CBCharacteristic *aChar in service.characteristics)
667 {
668 NSLog( @"Found Characteristic %@", aChar );
669
670 if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_INPUT_CHAR]] )
671 {
672 self.bleCharacteristicInput = aChar;
673 }
674 else if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_REPORT_CHAR]] )
675 {
676 self.bleCharacteristicReport = aChar;
677 [self.bleSteamController discoverDescriptorsForCharacteristic: aChar];
678 }
679 }
680 }
681}
682
683- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
684{
685 static uint64_t s_ticksLastOverflowReport = 0;
686
687 // receiving an input report is the final indicator that the user accepted a pairing
688 // request and that we successfully established notification. CoreBluetooth has no
689 // notification of the pairing acknowledgement, which is a bad oversight.
690 if ( self.ready == NO )
691 {
692 self.ready = YES;
693 HIDBLEManager.sharedInstance.nPendingPairs -= 1;
694 }
695
696 if ( [characteristic.UUID isEqual:_bleCharacteristicInput.UUID] )
697 {
698 NSData *data = [characteristic value];
699 if ( data.length != 19 )
700 {
701 NSLog( @"HIDBLE: incoming data is %lu bytes should be exactly 19", (unsigned long)data.length );
702 }
703 if ( !RingBuffer_write( &_inputReports, (const uint8_t *)data.bytes ) )
704 {
705 uint64_t ticksNow = mach_approximate_time();
706 if ( ticksNow - s_ticksLastOverflowReport > (5ull * NSEC_PER_SEC / 10) )
707 {
708 NSLog( @"HIDBLE: input report buffer overflow" );
709 s_ticksLastOverflowReport = ticksNow;
710 }
711 }
712 }
713 else if ( [characteristic.UUID isEqual:_bleCharacteristicReport.UUID] )
714 {
715 memset( _featureReport, 0, sizeof(_featureReport) );
716
717 if ( error != nil )
718 {
719 NSLog( @"HIDBLE: get_feature_report error: %@", error );
720 _waitStateForReadFeatureReport = BLEDeviceWaitState_Error;
721 }
722 else
723 {
724 NSData *data = [characteristic value];
725 if ( data.length != 20 )
726 {
727 NSLog( @"HIDBLE: incoming data is %lu bytes should be exactly 20", (unsigned long)data.length );
728 }
729 memcpy( _featureReport, data.bytes, MIN( data.length, sizeof(_featureReport) ) );
730 _waitStateForReadFeatureReport = BLEDeviceWaitState_Complete;
731 }
732 }
733}
734
735- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
736{
737 if ( [characteristic.UUID isEqual:[CBUUID UUIDWithString:VALVE_REPORT_CHAR]] )
738 {
739 if ( error != nil )
740 {
741 NSLog( @"HIDBLE: write_feature_report error: %@", error );
742 _waitStateForWriteFeatureReport = BLEDeviceWaitState_Error;
743 }
744 else
745 {
746 _waitStateForWriteFeatureReport = BLEDeviceWaitState_Complete;
747 }
748 }
749}
750
751- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
752{
753 NSLog( @"didUpdateNotifcationStateForCharacteristic %@ (%@)", characteristic, error );
754}
755
756@end
757
758
759#pragma mark hid_api implementation
760
761struct hid_device_ {
762 void *device_handle;
763 int blocking;
764 struct hid_device_info* device_info;
765 hid_device *next;
766};
767
768int HID_API_EXPORT HID_API_CALL hid_init(void)
769{
770 return ( HIDBLEManager.sharedInstance == nil ) ? -1 : 0;
771}
772
773int HID_API_EXPORT HID_API_CALL hid_exit(void)
774{
775 return 0;
776}
777
778void HID_API_EXPORT HID_API_CALL hid_ble_scan( int bStart )
779{
780 HIDBLEManager *bleManager = HIDBLEManager.sharedInstance;
781 if ( bStart )
782 {
783 [bleManager startScan:0];
784 }
785 else
786 {
787 [bleManager stopScan];
788 }
789}
790
791HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
792{
793 return NULL;
794}
795
796HID_API_EXPORT hid_device * HID_API_CALL hid_open_path( const char *path )
797{
798 hid_device *result = NULL;
799 NSString *nssPath = [NSString stringWithUTF8String:path];
800 HIDBLEManager *bleManager = HIDBLEManager.sharedInstance;
801 NSEnumerator<HIDBLEDevice *> *devices = [bleManager.deviceMap objectEnumerator];
802
803 for ( HIDBLEDevice *device in devices )
804 {
805 // we have the device but it hasn't found its service or characteristics until it is connected
806 if ( !device.ready || !device.connected || !device.bleCharacteristicInput )
807 continue;
808
809 if ( [device.bleSteamController.identifier.UUIDString isEqualToString:nssPath] )
810 {
811 result = (hid_device *)malloc( sizeof( hid_device ) );
812 memset( result, 0, sizeof( hid_device ) );
813 result->device_handle = (void*)CFBridgingRetain( device );
814 result->blocking = NO;
815 // enable reporting input events on the characteristic
816 [device.bleSteamController setNotifyValue:YES forCharacteristic:device.bleCharacteristicInput];
817 return result;
818 }
819 }
820 return result;
821}
822
823void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
824{
825 /* This function is identical to the Linux version. Platform independent. */
826 struct hid_device_info *d = devs;
827 while (d) {
828 struct hid_device_info *next = d->next;
829 free(d->path);
830 free(d->serial_number);
831 free(d->manufacturer_string);
832 free(d->product_string);
833 free(d);
834 d = next;
835 }
836}
837
838int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
839{
840 /* All Nonblocking operation is handled by the library. */
841 dev->blocking = !nonblock;
842
843 return 0;
844}
845
846static struct hid_device_info *create_device_info_for_hid_device(HIDBLEDevice *device)
847{
848 // We currently only support the Steam Controller
849 struct hid_device_info *device_info = (struct hid_device_info *)malloc( sizeof(struct hid_device_info) );
850 memset( device_info, 0, sizeof(struct hid_device_info) );
851 device_info->path = strdup( device.bleSteamController.identifier.UUIDString.UTF8String );
852 device_info->vendor_id = VALVE_USB_VID;
853 device_info->product_id = D0G_BLE2_PID;
854 device_info->product_string = wcsdup( L"Steam Controller" );
855 device_info->manufacturer_string = wcsdup( L"Valve Corporation" );
856 device_info->bus_type = HID_API_BUS_BLUETOOTH;
857 return device_info;
858}
859
860struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
861{ @autoreleasepool {
862 struct hid_device_info *root = NULL;
863
864 /* See if there are any devices we should skip in enumeration */
865 if (SDL_HIDAPI_ShouldIgnoreDevice(HID_API_BUS_BLUETOOTH, VALVE_USB_VID, D0G_BLE2_PID, 0, 0)) {
866 return NULL;
867 }
868
869 if ( ( vendor_id == 0 || vendor_id == VALVE_USB_VID ) &&
870 ( product_id == 0 || product_id == D0G_BLE2_PID ) )
871 {
872 HIDBLEManager *bleManager = HIDBLEManager.sharedInstance;
873 [bleManager updateConnectedSteamControllers:false];
874 NSEnumerator<HIDBLEDevice *> *devices = [bleManager.deviceMap objectEnumerator];
875 for ( HIDBLEDevice *device in devices )
876 {
877 // there are several brief windows in connecting to an already paired device and
878 // one long window waiting for users to confirm pairing where we don't want
879 // to consider a device ready - if we hand it back to SDL or another
880 // Steam Controller consumer, their additional SC setup work will fail
881 // in unusual/silent ways and we can actually corrupt the BLE stack for
882 // the entire system and kill the appletv remote's Menu button (!)
883 if ( device.bleSteamController.state != CBPeripheralStateConnected ||
884 device.connected == NO || device.ready == NO )
885 {
886 if ( device.ready == NO && device.bleCharacteristicInput != nil )
887 {
888 // attempt to register for input reports. this call will silently fail
889 // until the pairing finalizes with user acceptance. oh, apple.
890 [device.bleSteamController setNotifyValue:YES forCharacteristic:device.bleCharacteristicInput];
891 }
892 continue;
893 }
894 struct hid_device_info *device_info = create_device_info_for_hid_device(device);
895 device_info->next = root;
896 root = device_info;
897 }
898 }
899 return root;
900}}
901
902int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
903{
904 static wchar_t s_wszManufacturer[] = L"Valve Corporation";
905 wcsncpy( string, s_wszManufacturer, sizeof(s_wszManufacturer)/sizeof(s_wszManufacturer[0]) );
906 return 0;
907}
908
909int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
910{
911 static wchar_t s_wszProduct[] = L"Steam Controller";
912 wcsncpy( string, s_wszProduct, sizeof(s_wszProduct)/sizeof(s_wszProduct[0]) );
913 return 0;
914}
915
916int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
917{
918 static wchar_t s_wszSerial[] = L"12345";
919 wcsncpy( string, s_wszSerial, sizeof(s_wszSerial)/sizeof(s_wszSerial[0]) );
920 return 0;
921}
922
923int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
924{
925 return -1;
926}
927
928struct hid_device_info *hid_get_device_info(hid_device *dev)
929{
930 HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;
931
932 if (!dev->device_info) {
933 // Lazy initialize device_info
934 dev->device_info = create_device_info_for_hid_device(device_handle);
935 }
936
937 // create_device_info_for_hid_device will set an error if needed
938 return dev->device_info;
939}
940
941int hid_get_report_descriptor(hid_device *device, unsigned char *buf, size_t buf_size)
942{
943 // Not implemented
944 return -1;
945}
946
947int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
948{
949 HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;
950
951 if ( !device_handle.connected )
952 return -1;
953
954 return [device_handle send_report:data length:length];
955}
956
957void HID_API_EXPORT hid_close(hid_device *dev)
958{
959 HIDBLEDevice *device_handle = CFBridgingRelease( dev->device_handle );
960
961 // disable reporting input events on the characteristic
962 if ( device_handle.connected ) {
963 [device_handle.bleSteamController setNotifyValue:NO forCharacteristic:device_handle.bleCharacteristicInput];
964 }
965
966 hid_free_enumeration(dev->device_info);
967
968 free( dev );
969}
970
971int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
972{
973 HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;
974
975 if ( !device_handle.connected )
976 return -1;
977
978 return [device_handle send_feature_report:(hidFeatureReport *)(void *)data];
979}
980
981int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
982{
983 HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;
984
985 if ( !device_handle.connected )
986 return -1;
987
988 size_t written = [device_handle get_feature_report:data[0] into:data];
989
990 return written == length-1 ? (int)length : (int)written;
991}
992
993int HID_API_EXPORT hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
994{
995 // Not supported
996 return -1;
997}
998
999int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
1000{
1001 HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;
1002
1003 if ( !device_handle.connected )
1004 return -1;
1005
1006 return hid_read_timeout(dev, data, length, 0);
1007}
1008
1009int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1010{
1011 HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;
1012
1013 if ( !device_handle.connected )
1014 return -1;
1015
1016 if ( milliseconds != 0 )
1017 {
1018 NSLog( @"hid_read_timeout with non-zero wait" );
1019 }
1020 int result = (int)[device_handle read_input_report:data];
1021#if FEATURE_REPORT_LOGGING
1022 NSLog( @"HIDBLE:hid_read_timeout (%d) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", result,
1023 data[1], data[2], data[3], data[4], data[5], data[6],
1024 data[7], data[8], data[9], data[10], data[11], data[12],
1025 data[13], data[14], data[15], data[16], data[17], data[18],
1026 data[19] );
1027#endif
1028 return result;
1029}
1030
1031HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev)
1032{
1033 return NULL;
1034}
1035
1036#endif /* !SDL_HIDAPI_DISABLED */
1037
1038#endif /* SDL_PLATFORM_IOS || SDL_PLATFORM_TVOS */
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/libusb/CMakeLists.txt
new file mode 100644
index 0000000..4c458c5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/CMakeLists.txt
@@ -0,0 +1,107 @@
1cmake_minimum_required(VERSION 3.6.3...3.25 FATAL_ERROR)
2
3list(APPEND HIDAPI_PUBLIC_HEADERS "hidapi_libusb.h")
4
5add_library(hidapi_libusb
6 ${HIDAPI_PUBLIC_HEADERS}
7 hid.c
8)
9target_link_libraries(hidapi_libusb PUBLIC hidapi_include)
10
11if(TARGET usb-1.0)
12 target_link_libraries(hidapi_libusb PRIVATE usb-1.0)
13else()
14 include(FindPkgConfig)
15 pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0>=1.0.9)
16 target_link_libraries(hidapi_libusb PRIVATE PkgConfig::libusb)
17endif()
18
19find_package(Threads REQUIRED)
20target_link_libraries(hidapi_libusb PRIVATE Threads::Threads)
21
22if(HIDAPI_NO_ICONV)
23 target_compile_definitions(hidapi_libusb PRIVATE NO_ICONV)
24else()
25 if(NOT ANDROID)
26 include(CheckCSourceCompiles)
27
28 if(NOT CMAKE_VERSION VERSION_LESS 3.11)
29 message(STATUS "Check for Iconv")
30 find_package(Iconv)
31 if(Iconv_FOUND)
32 if(NOT Iconv_IS_BUILT_IN)
33 target_link_libraries(hidapi_libusb PRIVATE Iconv::Iconv)
34 set(CMAKE_REQUIRED_LIBRARIES "Iconv::Iconv")
35 if(NOT BUILD_SHARED_LIBS)
36 set(HIDAPI_NEED_EXPORT_ICONV TRUE PARENT_SCOPE)
37 endif()
38 endif()
39 else()
40 message(STATUS "Iconv Explicitly check '-liconv'")
41 # Sometime the build environment is not setup
42 # in a way CMake can find Iconv on its own by default.
43 # But if we simply link against iconv (-liconv), the build may succeed
44 # due to other compiler/link flags.
45 set(CMAKE_REQUIRED_LIBRARIES "iconv")
46 check_c_source_compiles("
47 #include <stddef.h>
48 #include <iconv.h>
49 int main() {
50 char *a, *b;
51 size_t i, j;
52 iconv_t ic;
53 ic = iconv_open(\"to\", \"from\");
54 iconv(ic, &a, &i, &b, &j);
55 iconv_close(ic);
56 }
57 "
58 Iconv_EXPLICITLY_AT_ENV)
59 if(Iconv_EXPLICITLY_AT_ENV)
60 message(STATUS "Iconv Explicitly check '-liconv' - Available")
61 target_link_libraries(hidapi_libusb PRIVATE iconv)
62 else()
63 message(FATAL_ERROR "Iconv is not found, make sure to provide it in the build environment")
64 endif()
65 endif()
66 else()
67 # otherwise there is 2 options:
68 # 1) iconv is provided by Standard C library and the build will be just fine
69 # 2) The _user_ has to provide additional compilation options for this project/target
70 endif()
71
72 # check for error: "conflicting types for 'iconv'"
73 check_c_source_compiles("#include<iconv.h>
74 extern size_t iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
75 int main() {}"
76 HIDAPI_ICONV_CONST)
77 if(HIDAPI_ICONV_CONST)
78 target_compile_definitions(hidapi_libusb PRIVATE "ICONV_CONST=const")
79 endif()
80 else()
81 # On Android Iconv is disabled on the code level anyway, so no issue;
82 endif()
83endif()
84
85set_target_properties(hidapi_libusb
86 PROPERTIES
87 EXPORT_NAME "libusb"
88 OUTPUT_NAME "hidapi-libusb"
89 VERSION ${PROJECT_VERSION}
90 SOVERSION ${PROJECT_VERSION_MAJOR}
91 PUBLIC_HEADER "${HIDAPI_PUBLIC_HEADERS}"
92)
93
94# compatibility with find_package()
95add_library(hidapi::libusb ALIAS hidapi_libusb)
96# compatibility with raw library link
97add_library(hidapi-libusb ALIAS hidapi_libusb)
98
99if(HIDAPI_INSTALL_TARGETS)
100 install(TARGETS hidapi_libusb EXPORT hidapi
101 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
102 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
103 PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/hidapi"
104 )
105endif()
106
107hidapi_configure_pc("${PROJECT_ROOT}/pc/hidapi-libusb.pc.in")
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile-manual b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile-manual
new file mode 100644
index 0000000..0acf707
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile-manual
@@ -0,0 +1,22 @@
1
2
3OS=$(shell uname)
4
5ifeq ($(OS), Linux)
6 FILE=Makefile.linux
7endif
8
9ifeq ($(OS), FreeBSD)
10 FILE=Makefile.freebsd
11endif
12
13ifeq ($(OS), Haiku)
14 FILE=Makefile.haiku
15endif
16
17ifeq ($(FILE), )
18all:
19 $(error Your platform ${OS} is not supported by hidapi/libusb at this time.)
20endif
21
22include $(FILE)
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.am b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.am
new file mode 100644
index 0000000..6964ebb
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.am
@@ -0,0 +1,34 @@
1AM_CPPFLAGS = -I$(top_srcdir)/hidapi $(CFLAGS_LIBUSB)
2
3if OS_LINUX
4lib_LTLIBRARIES = libhidapi-libusb.la
5libhidapi_libusb_la_SOURCES = hid.c
6libhidapi_libusb_la_LDFLAGS = $(LTLDFLAGS) $(PTHREAD_CFLAGS)
7libhidapi_libusb_la_LIBADD = $(LIBS_LIBUSB)
8endif
9
10if OS_FREEBSD
11lib_LTLIBRARIES = libhidapi.la
12libhidapi_la_SOURCES = hid.c
13libhidapi_la_LDFLAGS = $(LTLDFLAGS)
14libhidapi_la_LIBADD = $(LIBS_LIBUSB)
15endif
16
17if OS_KFREEBSD
18lib_LTLIBRARIES = libhidapi.la
19libhidapi_la_SOURCES = hid.c
20libhidapi_la_LDFLAGS = $(LTLDFLAGS)
21libhidapi_la_LIBADD = $(LIBS_LIBUSB)
22endif
23
24if OS_HAIKU
25lib_LTLIBRARIES = libhidapi.la
26libhidapi_la_SOURCES = hid.c
27libhidapi_la_LDFLAGS = $(LTLDFLAGS)
28libhidapi_la_LIBADD = $(LIBS_LIBUSB)
29endif
30
31hdrdir = $(includedir)/hidapi
32hdr_HEADERS = $(top_srcdir)/hidapi/hidapi.h hidapi_libusb.h
33
34EXTRA_DIST = Makefile-manual
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.freebsd b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.freebsd
new file mode 100644
index 0000000..c52b355
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.freebsd
@@ -0,0 +1,39 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: hidtest libs
10
11libs: libhidapi.so
12
13CC ?= cc
14CFLAGS ?= -Wall -g -fPIC
15
16COBJS = hid.o ../hidtest/test.o
17OBJS = $(COBJS)
18INCLUDES = -I../hidapi -I. -I/usr/local/include
19LDFLAGS = -L/usr/local/lib
20LIBS = -lusb -liconv -pthread
21
22
23# Console Test Program
24hidtest: $(OBJS)
25 $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
26
27# Shared Libs
28libhidapi.so: $(COBJS)
29 $(CC) $(LDFLAGS) -shared -Wl,-soname,$@.0 $^ -o $@ $(LIBS)
30
31# Objects
32$(COBJS): %.o: %.c
33 $(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@
34
35
36clean:
37 rm -f $(OBJS) hidtest libhidapi.so ../hidtest/hidtest.o
38
39.PHONY: clean libs
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.haiku b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.haiku
new file mode 100644
index 0000000..b3622ad
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.haiku
@@ -0,0 +1,39 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: hidtest libs
10
11libs: libhidapi.so
12
13CC ?= cc
14CFLAGS ?= -Wall -g -fPIC
15
16COBJS = hid.o ../hidtest/test.o
17OBJS = $(COBJS)
18INCLUDES = -I../hidapi -I. -I/usr/local/include
19LDFLAGS = -L/usr/local/lib
20LIBS = -lusb -liconv -pthread
21
22
23# Console Test Program
24hidtest: $(OBJS)
25 $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
26
27# Shared Libs
28libhidapi.so: $(COBJS)
29 $(CC) $(LDFLAGS) -shared -Wl,-soname,$@.0 $^ -o $@ $(LIBS)
30
31# Objects
32$(COBJS): %.o: %.c
33 $(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@
34
35
36clean:
37 rm -f $(OBJS) hidtest libhidapi.so ../hidtest/hidtest.o
38
39.PHONY: clean libs
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.linux b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.linux
new file mode 100644
index 0000000..527f6b3
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/Makefile.linux
@@ -0,0 +1,42 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: hidtest-libusb libs
10
11libs: libhidapi-libusb.so
12
13CC ?= gcc
14CFLAGS ?= -Wall -g -fpic
15
16LDFLAGS ?= -Wall -g
17
18COBJS_LIBUSB = hid.o
19COBJS = $(COBJS_LIBUSB) ../hidtest/test.o
20OBJS = $(COBJS)
21LIBS_USB = `pkg-config libusb-1.0 --libs` -lrt -lpthread
22LIBS = $(LIBS_USB)
23INCLUDES ?= -I../hidapi -I. `pkg-config libusb-1.0 --cflags`
24
25
26# Console Test Program
27hidtest-libusb: $(COBJS)
28 $(CC) $(LDFLAGS) $^ $(LIBS_USB) -o $@
29
30# Shared Libs
31libhidapi-libusb.so: $(COBJS_LIBUSB)
32 $(CC) $(LDFLAGS) $(LIBS_USB) -shared -fpic -Wl,-soname,$@.0 $^ -o $@
33
34# Objects
35$(COBJS): %.o: %.c
36 $(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@
37
38
39clean:
40 rm -f $(OBJS) hidtest-libusb libhidapi-libusb.so ../hidtest/hidtest.o
41
42.PHONY: clean libs
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/hid.c b/contrib/SDL-3.2.8/src/hidapi/libusb/hid.c
new file mode 100644
index 0000000..f4b1ccb
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/hid.c
@@ -0,0 +1,2144 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Copyright 2022, All Rights Reserved.
11
12 At the discretion of the user of this library,
13 this software may be licensed under the terms of the
14 GNU General Public License v3, a BSD-Style license, or the
15 original HIDAPI license as outlined in the LICENSE.txt,
16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17 files located at the root of the source distribution.
18 These files may also be found in the public source
19 code repository located at:
20 https://github.com/libusb/hidapi .
21********************************************************/
22
23#ifndef HIDAPI_USING_SDL_RUNTIME
24#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
25
26/* C */
27#include <stdio.h>
28#include <string.h>
29#include <stdlib.h>
30#include <ctype.h>
31#include <locale.h>
32#include <errno.h>
33
34/* Unix */
35#include <unistd.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <sys/ioctl.h>
39#include <sys/utsname.h>
40#include <fcntl.h>
41#include <wchar.h>
42
43/* GNU / LibUSB */
44#include <libusb.h>
45#if !defined(__ANDROID__) && !defined(NO_ICONV)
46#include <iconv.h>
47#ifndef ICONV_CONST
48#define ICONV_CONST
49#endif
50#endif
51#endif /* HIDAPI_USING_SDL_RUNTIME */
52
53#include "hidapi_libusb.h"
54
55#ifndef HIDAPI_THREAD_MODEL_INCLUDE
56#define HIDAPI_THREAD_MODEL_INCLUDE "hidapi_thread_pthread.h"
57#endif
58#include HIDAPI_THREAD_MODEL_INCLUDE
59
60#ifdef __cplusplus
61extern "C" {
62#endif
63
64#ifdef DEBUG_PRINTF
65#define LOG(...) fprintf(stderr, __VA_ARGS__)
66#else
67#define LOG(...) do {} while (0)
68#endif
69
70#ifndef __FreeBSD__
71#define DETACH_KERNEL_DRIVER
72#endif
73
74/* Uncomment to enable the retrieval of Usage and Usage Page in
75hid_enumerate(). Warning, on platforms different from FreeBSD
76this is very invasive as it requires the detach
77and re-attach of the kernel driver. See comments inside hid_enumerate().
78libusb HIDAPI programs are encouraged to use the interface number
79instead to differentiate between interfaces on a composite HID device. */
80/*#define INVASIVE_GET_USAGE*/
81
82/* Linked List of input reports received from the device. */
83struct input_report {
84 uint8_t *data;
85 size_t len;
86 struct input_report *next;
87};
88
89
90struct hid_device_ {
91 /* Handle to the actual device. */
92 libusb_device_handle *device_handle;
93
94 /* USB Configuration Number of the device */
95 int config_number;
96 /* The interface number of the HID */
97 int interface;
98 int interface_class;
99 int interface_subclass;
100 int interface_protocol;
101
102 uint16_t report_descriptor_size;
103
104 /* Endpoint information */
105 int input_endpoint;
106 int output_endpoint;
107 int input_ep_max_packet_size;
108
109 /* Indexes of Strings */
110 int manufacturer_index;
111 int product_index;
112 int serial_index;
113 struct hid_device_info* device_info;
114
115 /* Whether blocking reads are used */
116 int blocking; /* boolean */
117
118 /* Read thread objects */
119 hidapi_thread_state thread_state;
120 int shutdown_thread;
121 int transfer_loop_finished;
122 struct libusb_transfer *transfer;
123
124 /* Quirks */
125 int skip_output_report_id;
126 int no_skip_output_report_id;
127 int no_output_reports_on_intr_ep;
128
129 /* List of received input reports. */
130 struct input_report *input_reports;
131
132 /* Was kernel driver detached by libusb */
133#ifdef DETACH_KERNEL_DRIVER
134 int is_driver_detached;
135#endif
136};
137
138static struct hid_api_version api_version = {
139 .major = HID_API_VERSION_MAJOR,
140 .minor = HID_API_VERSION_MINOR,
141 .patch = HID_API_VERSION_PATCH
142};
143
144static libusb_context *usb_context = NULL;
145
146uint16_t get_usb_code_for_current_locale(void);
147static int return_data(hid_device *dev, unsigned char *data, size_t length);
148
149static hid_device *new_hid_device(void)
150{
151 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
152 dev->blocking = 1;
153
154 hidapi_thread_state_init(&dev->thread_state);
155
156 return dev;
157}
158
159static void free_hid_device(hid_device *dev)
160{
161 /* Clean up the thread objects */
162 hidapi_thread_state_destroy(&dev->thread_state);
163
164 hid_free_enumeration(dev->device_info);
165
166 /* Free the device itself */
167 free(dev);
168}
169
170#if 0
171/*TODO: Implement this function on hidapi/libusb.. */
172static void register_error(hid_device *dev, const char *op)
173{
174
175}
176#endif
177
178/* Get bytes from a HID Report Descriptor.
179 Only call with a num_bytes of 0, 1, 2, or 4. */
180static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur)
181{
182 /* Return if there aren't enough bytes. */
183 if (cur + num_bytes >= len)
184 return 0;
185
186 if (num_bytes == 0)
187 return 0;
188 else if (num_bytes == 1) {
189 return rpt[cur+1];
190 }
191 else if (num_bytes == 2) {
192 return (rpt[cur+2] * 256 + rpt[cur+1]);
193 }
194 else if (num_bytes == 4) {
195 return (rpt[cur+4] * 0x01000000 +
196 rpt[cur+3] * 0x00010000 +
197 rpt[cur+2] * 0x00000100 +
198 rpt[cur+1] * 0x00000001);
199 }
200 else
201 return 0;
202}
203
204/* Retrieves the device's Usage Page and Usage from the report
205 descriptor. The algorithm is simple, as it just returns the first
206 Usage and Usage Page that it finds in the descriptor.
207 The return value is 0 on success and -1 on failure. */
208static int get_usage(uint8_t *report_descriptor, size_t size,
209 unsigned short *usage_page, unsigned short *usage)
210{
211 unsigned int i = 0;
212 int size_code;
213 int data_len, key_size;
214 int usage_found = 0, usage_page_found = 0;
215
216 while (i < size) {
217 int key = report_descriptor[i];
218 int key_cmd = key & 0xfc;
219
220 //printf("key: %02hhx\n", key);
221
222 if ((key & 0xf0) == 0xf0) {
223 /* This is a Long Item. The next byte contains the
224 length of the data section (value) for this key.
225 See the HID specification, version 1.11, section
226 6.2.2.3, titled "Long Items." */
227 if (i+1 < size)
228 data_len = report_descriptor[i+1];
229 else
230 data_len = 0; /* malformed report */
231 key_size = 3;
232 }
233 else {
234 /* This is a Short Item. The bottom two bits of the
235 key contain the size code for the data section
236 (value) for this key. Refer to the HID
237 specification, version 1.11, section 6.2.2.2,
238 titled "Short Items." */
239 size_code = key & 0x3;
240 switch (size_code) {
241 case 0:
242 case 1:
243 case 2:
244 data_len = size_code;
245 break;
246 case 3:
247 data_len = 4;
248 break;
249 default:
250 /* Can't ever happen since size_code is & 0x3 */
251 data_len = 0;
252 break;
253 }
254 key_size = 1;
255 }
256
257 if (key_cmd == 0x4) {
258 *usage_page = get_bytes(report_descriptor, size, data_len, i);
259 usage_page_found = 1;
260 //printf("Usage Page: %x\n", (uint32_t)*usage_page);
261 }
262 if (key_cmd == 0x8) {
263 if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */
264 *usage_page = get_bytes(report_descriptor, size, 2, i + 2);
265 usage_page_found = 1;
266 *usage = get_bytes(report_descriptor, size, 2, i);
267 usage_found = 1;
268 }
269 else {
270 *usage = get_bytes(report_descriptor, size, data_len, i);
271 usage_found = 1;
272 }
273 //printf("Usage: %x\n", (uint32_t)*usage);
274 }
275
276 if (usage_page_found && usage_found)
277 return 0; /* success */
278
279 /* Skip over this key and it's associated data */
280 i += data_len + key_size;
281 }
282
283 return -1; /* failure */
284}
285
286#if defined(__FreeBSD__) && __FreeBSD__ < 10
287/* The libusb version included in FreeBSD < 10 doesn't have this function. In
288 mainline libusb, it's inlined in libusb.h. This function will bear a striking
289 resemblance to that one, because there's about one way to code it.
290
291 Note that the data parameter is Unicode in UTF-16LE encoding.
292 Return value is the number of bytes in data, or LIBUSB_ERROR_*.
293 */
294static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
295 uint8_t descriptor_index, uint16_t lang_id,
296 unsigned char *data, int length)
297{
298 return libusb_control_transfer(dev,
299 LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */
300 LIBUSB_REQUEST_GET_DESCRIPTOR,
301 (LIBUSB_DT_STRING << 8) | descriptor_index,
302 lang_id, data, (uint16_t) length, 1000);
303}
304
305#endif
306
307
308/* Get the first language the device says it reports. This comes from
309 USB string #0. */
310static uint16_t get_first_language(libusb_device_handle *dev)
311{
312 uint16_t buf[32];
313 int len;
314
315 /* Get the string from libusb. */
316 len = libusb_get_string_descriptor(dev,
317 0x0, /* String ID */
318 0x0, /* Language */
319 (unsigned char*)buf,
320 sizeof(buf));
321 if (len < 4)
322 return 0x0;
323
324 return buf[1]; /* First two bytes are len and descriptor type. */
325}
326
327static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
328{
329 uint16_t buf[32];
330 int len;
331 int i;
332
333 /* Get the string from libusb. */
334 len = libusb_get_string_descriptor(dev,
335 0x0, /* String ID */
336 0x0, /* Language */
337 (unsigned char*)buf,
338 sizeof(buf));
339 if (len < 4)
340 return 0x0;
341
342
343 len /= 2; /* language IDs are two-bytes each. */
344 /* Start at index 1 because there are two bytes of protocol data. */
345 for (i = 1; i < len; i++) {
346 if (buf[i] == lang)
347 return 1;
348 }
349
350 return 0;
351}
352
353
354/* This function returns a newly allocated wide string containing the USB
355 device string numbered by the index. The returned string must be freed
356 by using free(). */
357static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
358{
359 char buf[512];
360 int len;
361 wchar_t *str = NULL;
362
363#if !defined(__ANDROID__) && !defined(NO_ICONV) /* we don't use iconv on Android, or when it is explicitly disabled */
364 wchar_t wbuf[256];
365 /* iconv variables */
366 iconv_t ic;
367 size_t inbytes;
368 size_t outbytes;
369 size_t res;
370 ICONV_CONST char *inptr;
371 char *outptr;
372#endif
373
374 /* Determine which language to use. */
375 uint16_t lang;
376 lang = get_usb_code_for_current_locale();
377 if (!is_language_supported(dev, lang))
378 lang = get_first_language(dev);
379
380 /* Get the string from libusb. */
381 len = libusb_get_string_descriptor(dev,
382 idx,
383 lang,
384 (unsigned char*)buf,
385 sizeof(buf));
386 if (len < 2) /* we always skip first 2 bytes */
387 return NULL;
388
389#if defined(__ANDROID__) || defined(NO_ICONV)
390
391 /* Bionic does not have iconv support nor wcsdup() function, so it
392 has to be done manually. The following code will only work for
393 code points that can be represented as a single UTF-16 character,
394 and will incorrectly convert any code points which require more
395 than one UTF-16 character.
396
397 Skip over the first character (2-bytes). */
398 len -= 2;
399 str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t));
400 int i;
401 for (i = 0; i < len / 2; i++) {
402 str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
403 }
404 str[len / 2] = 0x00000000;
405
406#else
407
408 /* buf does not need to be explicitly NULL-terminated because
409 it is only passed into iconv() which does not need it. */
410
411 /* Initialize iconv. */
412 ic = iconv_open("WCHAR_T", "UTF-16LE");
413 if (ic == (iconv_t)-1) {
414 LOG("iconv_open() failed\n");
415 return NULL;
416 }
417
418 /* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
419 Skip the first character (2-bytes). */
420 inptr = buf+2;
421 inbytes = len-2;
422 outptr = (char*) wbuf;
423 outbytes = sizeof(wbuf);
424 res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
425 if (res == (size_t)-1) {
426 LOG("iconv() failed\n");
427 goto err;
428 }
429
430 /* Write the terminating NULL. */
431 wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
432 if (outbytes >= sizeof(wbuf[0]))
433 *((wchar_t*)outptr) = 0x00000000;
434
435 /* Allocate and copy the string. */
436 str = wcsdup(wbuf);
437
438err:
439 iconv_close(ic);
440
441#endif
442
443 return str;
444}
445
446struct usb_string_cache_entry {
447 uint16_t vid;
448 uint16_t pid;
449 wchar_t *vendor;
450 wchar_t *product;
451};
452
453static struct usb_string_cache_entry *usb_string_cache = NULL;
454static size_t usb_string_cache_size = 0;
455static size_t usb_string_cache_insert_pos = 0;
456
457static int usb_string_cache_grow(void)
458{
459 struct usb_string_cache_entry *new_cache;
460 size_t allocSize;
461 size_t new_cache_size;
462
463 new_cache_size = usb_string_cache_size + 8;
464 allocSize = sizeof(struct usb_string_cache_entry) * new_cache_size;
465 new_cache = (struct usb_string_cache_entry *)realloc(usb_string_cache, allocSize);
466 if (!new_cache)
467 return -1;
468
469 usb_string_cache = new_cache;
470 usb_string_cache_size = new_cache_size;
471
472 return 0;
473}
474
475static void usb_string_cache_destroy(void)
476{
477 size_t i;
478 for (i = 0; i < usb_string_cache_insert_pos; i++) {
479 free(usb_string_cache[i].vendor);
480 free(usb_string_cache[i].product);
481 }
482 free(usb_string_cache);
483
484 usb_string_cache = NULL;
485 usb_string_cache_size = 0;
486 usb_string_cache_insert_pos = 0;
487}
488
489static struct usb_string_cache_entry *usb_string_cache_insert(void)
490{
491 struct usb_string_cache_entry *new_entry = NULL;
492 if (usb_string_cache_insert_pos >= usb_string_cache_size) {
493 if (usb_string_cache_grow() < 0)
494 return NULL;
495 }
496 new_entry = &usb_string_cache[usb_string_cache_insert_pos];
497 usb_string_cache_insert_pos++;
498 return new_entry;
499}
500
501static int usb_string_can_cache(uint16_t vid, uint16_t pid)
502{
503 if (!vid || !pid) {
504 /* We can't cache these, they aren't unique */
505 return 0;
506 }
507
508 if (vid == 0x0f0d && pid == 0x00dc) {
509 /* HORI reuses this VID/PID for many different products */
510 return 0;
511 }
512
513 /* We can cache these strings */
514 return 1;
515}
516
517static const struct usb_string_cache_entry *usb_string_cache_find(struct libusb_device_descriptor *desc, struct libusb_device_handle *handle)
518{
519 struct usb_string_cache_entry *entry = NULL;
520 size_t i;
521
522 /* Search for existing string cache entry */
523 for (i = 0; i < usb_string_cache_insert_pos; i++) {
524 entry = &usb_string_cache[i];
525 if (entry->vid != desc->idVendor)
526 continue;
527 if (entry->pid != desc->idProduct)
528 continue;
529 return entry;
530 }
531
532 /* Not found, create one. */
533 entry = usb_string_cache_insert();
534 if (!entry)
535 return NULL;
536
537 entry->vid = desc->idVendor;
538 entry->pid = desc->idProduct;
539 if (desc->iManufacturer > 0)
540 entry->vendor = get_usb_string(handle, desc->iManufacturer);
541 else
542 entry->vendor = NULL;
543 if (desc->iProduct > 0)
544 entry->product = get_usb_string(handle, desc->iProduct);
545 else
546 entry->product = NULL;
547
548 return entry;
549}
550
551/**
552 Max length of the result: "000-000.000.000.000.000.000.000:000.000" (39 chars).
553 64 is used for simplicity/alignment.
554*/
555static void get_path(char (*result)[64], libusb_device *dev, int config_number, int interface_number)
556{
557 char *str = *result;
558
559 /* Note that USB3 port count limit is 7; use 8 here for alignment */
560 uint8_t port_numbers[8] = {0, 0, 0, 0, 0, 0, 0, 0};
561 int num_ports = libusb_get_port_numbers(dev, port_numbers, 8);
562
563 if (num_ports > 0) {
564 int n = snprintf(str, sizeof("000-000"), "%u-%u", libusb_get_bus_number(dev), port_numbers[0]);
565 for (uint8_t i = 1; i < num_ports; i++) {
566 n += snprintf(&str[n], sizeof(".000"), ".%u", port_numbers[i]);
567 }
568 n += snprintf(&str[n], sizeof(":000.000"), ":%u.%u", (uint8_t)config_number, (uint8_t)interface_number);
569 str[n] = '\0';
570 } else {
571 /* Likely impossible, but check: USB3.0 specs limit number of ports to 7 and buffer size here is 8 */
572 if (num_ports == LIBUSB_ERROR_OVERFLOW) {
573 LOG("make_path() failed. buffer overflow error\n");
574 } else {
575 LOG("make_path() failed. unknown error\n");
576 }
577 str[0] = '\0';
578 }
579}
580
581static char *make_path(libusb_device *dev, int config_number, int interface_number)
582{
583 char str[64];
584 get_path(&str, dev, config_number, interface_number);
585 return strdup(str);
586}
587
588HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void)
589{
590 return &api_version;
591}
592
593HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
594{
595 return HID_API_VERSION_STR;
596}
597
598int HID_API_EXPORT hid_init(void)
599{
600 if (!usb_context) {
601 const char *locale;
602
603 /* Init Libusb */
604 if (libusb_init(&usb_context))
605 return -1;
606
607 /* Set the locale if it's not set. */
608 locale = setlocale(LC_CTYPE, NULL);
609 if (!locale)
610 (void) setlocale(LC_CTYPE, "");
611 }
612
613 return 0;
614}
615
616int HID_API_EXPORT hid_exit(void)
617{
618 usb_string_cache_destroy();
619
620 if (usb_context) {
621 libusb_exit(usb_context);
622 usb_context = NULL;
623 }
624
625 return 0;
626}
627
628static int hid_get_report_descriptor_libusb(libusb_device_handle *handle, int interface_num, uint16_t expected_report_descriptor_size, unsigned char *buf, size_t buf_size)
629{
630 unsigned char *tmp = (unsigned char *)malloc(HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
631
632 if (expected_report_descriptor_size > HID_API_MAX_REPORT_DESCRIPTOR_SIZE)
633 expected_report_descriptor_size = HID_API_MAX_REPORT_DESCRIPTOR_SIZE;
634
635 /* Get the HID Report Descriptor.
636 See USB HID Specification, section 7.1.1
637 */
638 int res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8), interface_num, tmp, expected_report_descriptor_size, 5000);
639 if (res >= 0) {
640 if (res > (int)buf_size)
641 res = (int)buf_size;
642
643 memcpy(buf, tmp, (size_t)res);
644 } else {
645 LOG("libusb_control_transfer() for getting the HID Report descriptor failed with %d: %s\n", res, libusb_error_name(res));
646 }
647 free(tmp);
648
649 return res;
650}
651
652/**
653 * Requires an opened device with *claimed interface*.
654 */
655static void fill_device_info_usage(struct hid_device_info *cur_dev, libusb_device_handle *handle, int interface_num, uint16_t expected_report_descriptor_size)
656{
657 unsigned char *hid_report_descriptor = malloc(HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
658 unsigned short page = 0, usage = 0;
659
660 int res = hid_get_report_descriptor_libusb(handle, interface_num, expected_report_descriptor_size, hid_report_descriptor, HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
661 if (res >= 0) {
662 /* Parse the usage and usage page
663 out of the report descriptor. */
664 get_usage(hid_report_descriptor, res, &page, &usage);
665 }
666
667 cur_dev->usage_page = page;
668 cur_dev->usage = usage;
669}
670
671#ifdef INVASIVE_GET_USAGE
672static void invasive_fill_device_info_usage(struct hid_device_info *cur_dev, libusb_device_handle *handle, int interface_num, uint16_t report_descriptor_size)
673{
674 int res = 0;
675
676#ifdef DETACH_KERNEL_DRIVER
677 int detached = 0;
678 /* Usage Page and Usage */
679 res = libusb_kernel_driver_active(handle, interface_num);
680 if (res == 1) {
681 res = libusb_detach_kernel_driver(handle, interface_num);
682 if (res < 0)
683 LOG("Couldn't detach kernel driver, even though a kernel driver was attached.\n");
684 else
685 detached = 1;
686 }
687#endif
688
689 res = libusb_claim_interface(handle, interface_num);
690 if (res >= 0) {
691 fill_device_info_usage(cur_dev, handle, interface_num, report_descriptor_size);
692
693 /* Release the interface */
694 res = libusb_release_interface(handle, interface_num);
695 if (res < 0)
696 LOG("Can't release the interface.\n");
697 }
698 else
699 LOG("Can't claim interface: (%d) %s\n", res, libusb_error_name(res));
700
701#ifdef DETACH_KERNEL_DRIVER
702 /* Re-attach kernel driver if necessary. */
703 if (detached) {
704 res = libusb_attach_kernel_driver(handle, interface_num);
705 if (res < 0)
706 LOG("Couldn't re-attach kernel driver.\n");
707 }
708#endif
709}
710#endif /* INVASIVE_GET_USAGE */
711
712/**
713 * Create and fill up most of hid_device_info fields.
714 * usage_page/usage is not filled up.
715 */
716static struct hid_device_info * create_device_info_for_device(libusb_device *device, libusb_device_handle *handle, struct libusb_device_descriptor *desc, int config_number, int interface_num, int interface_class, int interface_subclass, int interface_protocol)
717{
718 struct hid_device_info *cur_dev = calloc(1, sizeof(struct hid_device_info));
719 if (cur_dev == NULL) {
720 return NULL;
721 }
722
723 /* VID/PID */
724 cur_dev->vendor_id = desc->idVendor;
725 cur_dev->product_id = desc->idProduct;
726
727 cur_dev->release_number = desc->bcdDevice;
728
729 cur_dev->interface_number = interface_num;
730 cur_dev->interface_class = interface_class;
731 cur_dev->interface_subclass = interface_subclass;
732 cur_dev->interface_protocol = interface_protocol;
733
734 cur_dev->bus_type = HID_API_BUS_USB;
735
736 cur_dev->path = make_path(device, config_number, interface_num);
737
738 if (!handle) {
739 return cur_dev;
740 }
741
742 if (desc->iSerialNumber > 0)
743 cur_dev->serial_number = get_usb_string(handle, desc->iSerialNumber);
744
745 /* Manufacturer and Product strings */
746 const struct usb_string_cache_entry *string_cache;
747 if (usb_string_can_cache(desc->idVendor, desc->idProduct) &&
748 (string_cache = usb_string_cache_find(desc, handle)) != NULL) {
749 if (string_cache->vendor) {
750 cur_dev->manufacturer_string = wcsdup(string_cache->vendor);
751 }
752 if (string_cache->product) {
753 cur_dev->product_string = wcsdup(string_cache->product);
754 }
755 } else {
756 if (desc->iManufacturer > 0)
757 cur_dev->manufacturer_string = get_usb_string(handle, desc->iManufacturer);
758 if (desc->iProduct > 0)
759 cur_dev->product_string = get_usb_string(handle, desc->iProduct);
760 }
761
762 return cur_dev;
763}
764
765static uint16_t get_report_descriptor_size_from_interface_descriptors(const struct libusb_interface_descriptor *intf_desc)
766{
767 int i = 0;
768 int found_hid_report_descriptor = 0;
769 uint16_t result = HID_API_MAX_REPORT_DESCRIPTOR_SIZE;
770 const unsigned char *extra = intf_desc->extra;
771 int extra_length = intf_desc->extra_length;
772
773 /*
774 "extra" contains a HID descriptor
775 See section 6.2.1 of HID 1.1 specification.
776 */
777
778 while (extra_length >= 2) { /* Descriptor header: bLength/bDescriptorType */
779 if (extra[1] == LIBUSB_DT_HID) { /* bDescriptorType */
780 if (extra_length < 6) {
781 LOG("Broken HID descriptor: not enough data\n");
782 break;
783 }
784 unsigned char bNumDescriptors = extra[5];
785 if (extra_length < (6 + 3 * bNumDescriptors)) {
786 LOG("Broken HID descriptor: not enough data for Report metadata\n");
787 break;
788 }
789 for (i = 0; i < bNumDescriptors; i++) {
790 if (extra[6 + 3 * i] == LIBUSB_DT_REPORT) {
791 result = (uint16_t)extra[6 + 3 * i + 2] << 8 | extra[6 + 3 * i + 1];
792 found_hid_report_descriptor = 1;
793 break;
794 }
795 }
796
797 if (!found_hid_report_descriptor) {
798 /* We expect to find exactly 1 HID descriptor (LIBUSB_DT_HID)
799 which should contain exactly one HID Report Descriptor metadata (LIBUSB_DT_REPORT). */
800 LOG("Broken HID descriptor: missing Report descriptor\n");
801 }
802 break;
803 }
804
805 if (extra[0] == 0) { /* bLength */
806 LOG("Broken HID Interface descriptors: zero-sized descriptor\n");
807 break;
808 }
809
810 /* Iterate over to the next Descriptor */
811 extra_length -= extra[0];
812 extra += extra[0];
813 }
814
815 return result;
816}
817
818static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
819{
820 static const int xb360_iface_subclass = 93;
821 static const int xb360_iface_protocol = 1; /* Wired */
822 static const int xb360w_iface_protocol = 129; /* Wireless */
823 static const int supported_vendors[] = {
824 0x0079, /* GPD Win 2 */
825 0x044f, /* Thrustmaster */
826 0x045e, /* Microsoft */
827 0x046d, /* Logitech */
828 0x056e, /* Elecom */
829 0x06a3, /* Saitek */
830 0x0738, /* Mad Catz */
831 0x07ff, /* Mad Catz */
832 0x0e6f, /* PDP */
833 0x0f0d, /* Hori */
834 0x1038, /* SteelSeries */
835 0x11c9, /* Nacon */
836 0x12ab, /* Unknown */
837 0x1430, /* RedOctane */
838 0x146b, /* BigBen */
839 0x1532, /* Razer Sabertooth */
840 0x15e4, /* Numark */
841 0x162e, /* Joytech */
842 0x1689, /* Razer Onza */
843 0x1949, /* Lab126, Inc. */
844 0x1bad, /* Harmonix */
845 0x20d6, /* PowerA */
846 0x24c6, /* PowerA */
847 0x2c22, /* Qanba */
848 0x2dc8, /* 8BitDo */
849 0x9886, /* ASTRO Gaming */
850 };
851
852 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
853 intf_desc->bInterfaceSubClass == xb360_iface_subclass &&
854 (intf_desc->bInterfaceProtocol == xb360_iface_protocol ||
855 intf_desc->bInterfaceProtocol == xb360w_iface_protocol)) {
856 size_t i;
857 for (i = 0; i < sizeof(supported_vendors)/sizeof(supported_vendors[0]); ++i) {
858 if (vendor_id == supported_vendors[i]) {
859 return 1;
860 }
861 }
862 }
863 return 0;
864}
865
866static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
867{
868 static const int xb1_iface_subclass = 71;
869 static const int xb1_iface_protocol = 208;
870 static const int supported_vendors[] = {
871 0x03f0, /* HP */
872 0x044f, /* Thrustmaster */
873 0x045e, /* Microsoft */
874 0x0738, /* Mad Catz */
875 0x0b05, /* ASUS */
876 0x0e6f, /* PDP */
877 0x0f0d, /* Hori */
878 0x10f5, /* Turtle Beach */
879 0x1532, /* Razer Wildcat */
880 0x20d6, /* PowerA */
881 0x24c6, /* PowerA */
882 0x2dc8, /* 8BitDo */
883 0x2e24, /* Hyperkin */
884 0x3537, /* GameSir */
885 };
886
887 if (intf_desc->bInterfaceNumber == 0 &&
888 intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
889 intf_desc->bInterfaceSubClass == xb1_iface_subclass &&
890 intf_desc->bInterfaceProtocol == xb1_iface_protocol) {
891 size_t i;
892 for (i = 0; i < sizeof(supported_vendors)/sizeof(supported_vendors[0]); ++i) {
893 if (vendor_id == supported_vendors[i]) {
894 return 1;
895 }
896 }
897 }
898 return 0;
899}
900
901static int should_enumerate_interface(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
902{
903#if 0
904 printf("Checking interface 0x%x %d/%d/%d/%d\n", vendor_id, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol);
905#endif
906
907 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID)
908 return 1;
909
910 /* Also enumerate Xbox 360 controllers */
911 if (is_xbox360(vendor_id, intf_desc))
912 return 1;
913
914 /* Also enumerate Xbox One controllers */
915 if (is_xboxone(vendor_id, intf_desc))
916 return 1;
917
918 return 0;
919}
920
921struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
922{
923 libusb_device **devs;
924 libusb_device *dev;
925 libusb_device_handle *handle = NULL;
926 ssize_t num_devs;
927 int i = 0;
928
929 struct hid_device_info *root = NULL; /* return object */
930 struct hid_device_info *cur_dev = NULL;
931
932 if(hid_init() < 0)
933 return NULL;
934
935 num_devs = libusb_get_device_list(usb_context, &devs);
936 if (num_devs < 0)
937 return NULL;
938 while ((dev = devs[i++]) != NULL) {
939 struct libusb_device_descriptor desc;
940 struct libusb_config_descriptor *conf_desc = NULL;
941 int j, k;
942
943 int res = libusb_get_device_descriptor(dev, &desc);
944 if (res < 0)
945 continue;
946
947 unsigned short dev_vid = desc.idVendor;
948 unsigned short dev_pid = desc.idProduct;
949
950 if ((vendor_id != 0x0 && vendor_id != dev_vid) ||
951 (product_id != 0x0 && product_id != dev_pid)) {
952 continue;
953 }
954
955#ifdef HIDAPI_IGNORE_DEVICE
956 /* See if there are any devices we should skip in enumeration */
957 if (HIDAPI_IGNORE_DEVICE(HID_API_BUS_USB, dev_vid, dev_pid, 0, 0)) {
958 continue;
959 }
960#endif
961
962 res = libusb_get_active_config_descriptor(dev, &conf_desc);
963 if (res < 0)
964 libusb_get_config_descriptor(dev, 0, &conf_desc);
965 if (conf_desc) {
966 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
967 const struct libusb_interface *intf = &conf_desc->interface[j];
968 for (k = 0; k < intf->num_altsetting; k++) {
969 const struct libusb_interface_descriptor *intf_desc;
970 intf_desc = &intf->altsetting[k];
971 if (should_enumerate_interface(dev_vid, intf_desc)) {
972 struct hid_device_info *tmp;
973
974 res = libusb_open(dev, &handle);
975
976#ifdef __ANDROID__
977 if (handle) {
978 /* There is (a potential) libusb Android backend, in which
979 device descriptor is not accurate up until the device is opened.
980 https://github.com/libusb/libusb/pull/874#discussion_r632801373
981 A workaround is to re-read the descriptor again.
982 Even if it is not going to be accepted into libusb master,
983 having it here won't do any harm, since reading the device descriptor
984 is as cheap as copy 18 bytes of data. */
985 libusb_get_device_descriptor(dev, &desc);
986 }
987#endif
988
989 tmp = create_device_info_for_device(dev, handle, &desc, conf_desc->bConfigurationValue, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol);
990 if (tmp) {
991#ifdef INVASIVE_GET_USAGE
992 /* TODO: have a runtime check for this section. */
993
994 /*
995 This section is removed because it is too
996 invasive on the system. Getting a Usage Page
997 and Usage requires parsing the HID Report
998 descriptor. Getting a HID Report descriptor
999 involves claiming the interface. Claiming the
1000 interface involves detaching the kernel driver.
1001 Detaching the kernel driver is hard on the system
1002 because it will unclaim interfaces (if another
1003 app has them claimed) and the re-attachment of
1004 the driver will sometimes change /dev entry names.
1005 It is for these reasons that this section is
1006 optional. For composite devices, use the interface
1007 field in the hid_device_info struct to distinguish
1008 between interfaces. */
1009 if (handle) {
1010 uint16_t report_descriptor_size = get_report_descriptor_size_from_interface_descriptors(intf_desc);
1011
1012 invasive_fill_device_info_usage(tmp, handle, intf_desc->bInterfaceNumber, report_descriptor_size);
1013 }
1014#endif /* INVASIVE_GET_USAGE */
1015
1016 if (cur_dev) {
1017 cur_dev->next = tmp;
1018 }
1019 else {
1020 root = tmp;
1021 }
1022 cur_dev = tmp;
1023 }
1024
1025 if (res >= 0) {
1026 libusb_close(handle);
1027 handle = NULL;
1028 }
1029 break;
1030 }
1031 } /* altsettings */
1032 } /* interfaces */
1033 libusb_free_config_descriptor(conf_desc);
1034 }
1035 }
1036
1037 libusb_free_device_list(devs, 1);
1038
1039 return root;
1040}
1041
1042void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
1043{
1044 struct hid_device_info *d = devs;
1045 while (d) {
1046 struct hid_device_info *next = d->next;
1047 free(d->path);
1048 free(d->serial_number);
1049 free(d->manufacturer_string);
1050 free(d->product_string);
1051 free(d);
1052 d = next;
1053 }
1054}
1055
1056hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
1057{
1058 struct hid_device_info *devs, *cur_dev;
1059 const char *path_to_open = NULL;
1060 hid_device *handle = NULL;
1061
1062 devs = hid_enumerate(vendor_id, product_id);
1063 cur_dev = devs;
1064 while (cur_dev) {
1065 if (cur_dev->vendor_id == vendor_id &&
1066 cur_dev->product_id == product_id) {
1067 if (serial_number) {
1068 if (cur_dev->serial_number &&
1069 wcscmp(serial_number, cur_dev->serial_number) == 0) {
1070 path_to_open = cur_dev->path;
1071 break;
1072 }
1073 }
1074 else {
1075 path_to_open = cur_dev->path;
1076 break;
1077 }
1078 }
1079 cur_dev = cur_dev->next;
1080 }
1081
1082 if (path_to_open) {
1083 /* Open the device */
1084 handle = hid_open_path(path_to_open);
1085 }
1086
1087 hid_free_enumeration(devs);
1088
1089 return handle;
1090}
1091
1092static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
1093{
1094 hid_device *dev = transfer->user_data;
1095 int res;
1096
1097 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
1098
1099 struct input_report *rpt = (struct input_report*) malloc(sizeof(*rpt));
1100 rpt->data = (uint8_t*) malloc(transfer->actual_length);
1101 memcpy(rpt->data, transfer->buffer, transfer->actual_length);
1102 rpt->len = transfer->actual_length;
1103 rpt->next = NULL;
1104
1105 hidapi_thread_mutex_lock(&dev->thread_state);
1106
1107 /* Attach the new report object to the end of the list. */
1108 if (dev->input_reports == NULL) {
1109 /* The list is empty. Put it at the root. */
1110 dev->input_reports = rpt;
1111 hidapi_thread_cond_signal(&dev->thread_state);
1112 }
1113 else {
1114 /* Find the end of the list and attach. */
1115 struct input_report *cur = dev->input_reports;
1116 int num_queued = 0;
1117 while (cur->next != NULL) {
1118 cur = cur->next;
1119 num_queued++;
1120 }
1121 cur->next = rpt;
1122
1123 /* Pop one off if we've reached 30 in the queue. This
1124 way we don't grow forever if the user never reads
1125 anything from the device. */
1126 if (num_queued > 30) {
1127 return_data(dev, NULL, 0);
1128 }
1129 }
1130 hidapi_thread_mutex_unlock(&dev->thread_state);
1131 }
1132 else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
1133 dev->shutdown_thread = 1;
1134 }
1135 else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) {
1136 dev->shutdown_thread = 1;
1137 }
1138 else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
1139 //LOG("Timeout (normal)\n");
1140 }
1141 else {
1142 LOG("Unknown transfer code: %d\n", transfer->status);
1143 }
1144
1145 if (dev->shutdown_thread) {
1146 dev->transfer_loop_finished = 1;
1147 return;
1148 }
1149
1150 /* Re-submit the transfer object. */
1151 res = libusb_submit_transfer(transfer);
1152 if (res != 0) {
1153 LOG("Unable to submit URB: (%d) %s\n", res, libusb_error_name(res));
1154 dev->shutdown_thread = 1;
1155 dev->transfer_loop_finished = 1;
1156 }
1157}
1158
1159
1160static void *read_thread(void *param)
1161{
1162 int res;
1163 hid_device *dev = param;
1164 uint8_t *buf;
1165 const size_t length = dev->input_ep_max_packet_size;
1166
1167 /* Set up the transfer object. */
1168 buf = (uint8_t*) malloc(length);
1169 dev->transfer = libusb_alloc_transfer(0);
1170 libusb_fill_interrupt_transfer(dev->transfer,
1171 dev->device_handle,
1172 dev->input_endpoint,
1173 buf,
1174 (int) length,
1175 read_callback,
1176 dev,
1177 5000/*timeout*/);
1178
1179 /* Make the first submission. Further submissions are made
1180 from inside read_callback() */
1181 res = libusb_submit_transfer(dev->transfer);
1182 if(res < 0) {
1183 LOG("libusb_submit_transfer failed: %d %s. Stopping read_thread from running\n", res, libusb_error_name(res));
1184 dev->shutdown_thread = 1;
1185 dev->transfer_loop_finished = 1;
1186 }
1187
1188 /* Notify the main thread that the read thread is up and running. */
1189 hidapi_thread_barrier_wait(&dev->thread_state);
1190
1191 /* Handle all the events. */
1192 while (!dev->shutdown_thread) {
1193 res = libusb_handle_events(usb_context);
1194 if (res < 0) {
1195 /* There was an error. */
1196 LOG("read_thread(): (%d) %s\n", res, libusb_error_name(res));
1197
1198 /* Break out of this loop only on fatal error.*/
1199 if (res != LIBUSB_ERROR_BUSY &&
1200 res != LIBUSB_ERROR_TIMEOUT &&
1201 res != LIBUSB_ERROR_OVERFLOW &&
1202 res != LIBUSB_ERROR_INTERRUPTED) {
1203 dev->shutdown_thread = 1;
1204 break;
1205 }
1206 }
1207 }
1208
1209 /* Cancel any transfer that may be pending. This call will fail
1210 if no transfers are pending, but that's OK. */
1211 libusb_cancel_transfer(dev->transfer);
1212
1213 while (!dev->transfer_loop_finished)
1214 libusb_handle_events_completed(usb_context, &dev->transfer_loop_finished);
1215
1216 /* Now that the read thread is stopping, Wake any threads which are
1217 waiting on data (in hid_read_timeout()). Do this under a mutex to
1218 make sure that a thread which is about to go to sleep waiting on
1219 the condition actually will go to sleep before the condition is
1220 signaled. */
1221 hidapi_thread_mutex_lock(&dev->thread_state);
1222 hidapi_thread_cond_broadcast(&dev->thread_state);
1223 hidapi_thread_mutex_unlock(&dev->thread_state);
1224
1225 /* The dev->transfer->buffer and dev->transfer objects are cleaned up
1226 in hid_close(). They are not cleaned up here because this thread
1227 could end either due to a disconnect or due to a user
1228 call to hid_close(). In both cases the objects can be safely
1229 cleaned up after the call to hidapi_thread_join() (in hid_close()), but
1230 since hid_close() calls libusb_cancel_transfer(), on these objects,
1231 they can not be cleaned up here. */
1232
1233 return NULL;
1234}
1235
1236static void init_xbox360(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, const struct libusb_config_descriptor *conf_desc)
1237{
1238 (void)conf_desc;
1239
1240 if ((idVendor == 0x05ac && idProduct == 0x055b) /* Gamesir-G3w */ ||
1241 idVendor == 0x0f0d /* Hori Xbox controllers */) {
1242 unsigned char data[20];
1243
1244 /* The HORIPAD FPS for Nintendo Switch requires this to enable input reports.
1245 This VID/PID is also shared with other HORI controllers, but they all seem
1246 to be fine with this as well.
1247 */
1248 memset(data, 0, sizeof(data));
1249 libusb_control_transfer(device_handle, 0xC1, 0x01, 0x100, 0x0, data, sizeof(data), 100);
1250 }
1251}
1252
1253static void init_xboxone(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, const struct libusb_config_descriptor *conf_desc)
1254{
1255 static const int vendor_microsoft = 0x045e;
1256 static const int xb1_iface_subclass = 71;
1257 static const int xb1_iface_protocol = 208;
1258 int j, k, res;
1259
1260 (void)idProduct;
1261
1262 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
1263 const struct libusb_interface *intf = &conf_desc->interface[j];
1264 for (k = 0; k < intf->num_altsetting; k++) {
1265 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1266 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
1267 intf_desc->bInterfaceSubClass == xb1_iface_subclass &&
1268 intf_desc->bInterfaceProtocol == xb1_iface_protocol) {
1269 int bSetAlternateSetting = 0;
1270
1271 /* Newer Microsoft Xbox One controllers have a high speed alternate setting */
1272 if (idVendor == vendor_microsoft &&
1273 intf_desc->bInterfaceNumber == 0 && intf_desc->bAlternateSetting == 1) {
1274 bSetAlternateSetting = 1;
1275 } else if (intf_desc->bInterfaceNumber != 0 && intf_desc->bAlternateSetting == 0) {
1276 bSetAlternateSetting = 1;
1277 }
1278
1279 if (bSetAlternateSetting) {
1280 res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber);
1281 if (res < 0) {
1282 LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
1283 continue;
1284 }
1285
1286 LOG("Setting alternate setting for VID/PID 0x%x/0x%x interface %d to %d\n", idVendor, idProduct, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting);
1287
1288 res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting);
1289 if (res < 0) {
1290 LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res);
1291 }
1292
1293 libusb_release_interface(device_handle, intf_desc->bInterfaceNumber);
1294 }
1295 }
1296 }
1297 }
1298}
1299
1300static void calculate_device_quirks(hid_device *dev, unsigned short idVendor, unsigned short idProduct)
1301{
1302 static const int VENDOR_SONY = 0x054c;
1303 static const int PRODUCT_PS3_CONTROLLER = 0x0268;
1304 static const int PRODUCT_NAVIGATION_CONTROLLER = 0x042f;
1305
1306 if (idVendor == VENDOR_SONY &&
1307 (idProduct == PRODUCT_PS3_CONTROLLER || idProduct == PRODUCT_NAVIGATION_CONTROLLER)) {
1308 dev->skip_output_report_id = 1;
1309 dev->no_output_reports_on_intr_ep = 1;
1310 }
1311}
1312
1313static int hidapi_initialize_device(hid_device *dev, const struct libusb_interface_descriptor *intf_desc, const struct libusb_config_descriptor *conf_desc)
1314{
1315 int i =0;
1316 int res = 0;
1317 struct libusb_device_descriptor desc;
1318 libusb_get_device_descriptor(libusb_get_device(dev->device_handle), &desc);
1319
1320#ifdef DETACH_KERNEL_DRIVER
1321 /* Detach the kernel driver, but only if the
1322 device is managed by the kernel */
1323 dev->is_driver_detached = 0;
1324 if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) {
1325 res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber);
1326 if (res < 0) {
1327 LOG("Unable to detach Kernel Driver: (%d) %s\n", res, libusb_error_name(res));
1328 return 0;
1329 }
1330 else {
1331 dev->is_driver_detached = 1;
1332 LOG("Driver successfully detached from kernel.\n");
1333 }
1334 }
1335#endif
1336 res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber);
1337 if (res < 0) {
1338 LOG("can't claim interface %d: (%d) %s\n", intf_desc->bInterfaceNumber, res, libusb_error_name(res));
1339
1340#ifdef DETACH_KERNEL_DRIVER
1341 if (dev->is_driver_detached) {
1342 res = libusb_attach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber);
1343 if (res < 0)
1344 LOG("Failed to reattach the driver to kernel: (%d) %s\n", res, libusb_error_name(res));
1345 }
1346#endif
1347 return 0;
1348 }
1349
1350 /* Initialize XBox 360 controllers */
1351 if (is_xbox360(desc.idVendor, intf_desc)) {
1352 dev->no_skip_output_report_id = 1;
1353 init_xbox360(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
1354 }
1355
1356 /* Initialize XBox One controllers */
1357 if (is_xboxone(desc.idVendor, intf_desc)) {
1358 init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
1359 }
1360
1361 /* Store off the string descriptor indexes */
1362 dev->manufacturer_index = desc.iManufacturer;
1363 dev->product_index = desc.iProduct;
1364 dev->serial_index = desc.iSerialNumber;
1365
1366 /* Store off the USB information */
1367 dev->config_number = conf_desc->bConfigurationValue;
1368 dev->interface = intf_desc->bInterfaceNumber;
1369 dev->interface_class = intf_desc->bInterfaceClass;
1370 dev->interface_subclass = intf_desc->bInterfaceSubClass;
1371 dev->interface_protocol = intf_desc->bInterfaceProtocol;
1372
1373 dev->report_descriptor_size = get_report_descriptor_size_from_interface_descriptors(intf_desc);
1374
1375 dev->input_endpoint = 0;
1376 dev->input_ep_max_packet_size = 0;
1377 dev->output_endpoint = 0;
1378
1379 /* Find the INPUT and OUTPUT endpoints. An
1380 OUTPUT endpoint is not required. */
1381 for (i = 0; i < intf_desc->bNumEndpoints; i++) {
1382 const struct libusb_endpoint_descriptor *ep
1383 = &intf_desc->endpoint[i];
1384
1385 /* Determine the type and direction of this
1386 endpoint. */
1387 int is_interrupt =
1388 (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
1389 == LIBUSB_TRANSFER_TYPE_INTERRUPT;
1390 int is_output =
1391 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
1392 == LIBUSB_ENDPOINT_OUT;
1393 int is_input =
1394 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
1395 == LIBUSB_ENDPOINT_IN;
1396
1397 /* Decide whether to use it for input or output. */
1398 if (dev->input_endpoint == 0 &&
1399 is_interrupt && is_input) {
1400 /* Use this endpoint for INPUT */
1401 dev->input_endpoint = ep->bEndpointAddress;
1402 dev->input_ep_max_packet_size = ep->wMaxPacketSize;
1403 }
1404 if (dev->output_endpoint == 0 &&
1405 is_interrupt && is_output) {
1406 /* Use this endpoint for OUTPUT */
1407 dev->output_endpoint = ep->bEndpointAddress;
1408 }
1409 }
1410
1411 calculate_device_quirks(dev, desc.idVendor, desc.idProduct);
1412
1413 hidapi_thread_create(&dev->thread_state, read_thread, dev);
1414
1415 /* Wait here for the read thread to be initialized. */
1416 hidapi_thread_barrier_wait(&dev->thread_state);
1417 return 1;
1418}
1419
1420
1421HID_API_EXPORT hid_device *hid_open_path(const char *path)
1422{
1423 hid_device *dev = NULL;
1424
1425 libusb_device **devs = NULL;
1426 libusb_device *usb_dev = NULL;
1427 int res = 0;
1428 int d = 0;
1429 int good_open = 0;
1430
1431 if(hid_init() < 0)
1432 return NULL;
1433
1434 dev = new_hid_device();
1435
1436 libusb_get_device_list(usb_context, &devs);
1437 while ((usb_dev = devs[d++]) != NULL && !good_open) {
1438 struct libusb_device_descriptor desc;
1439 struct libusb_config_descriptor *conf_desc = NULL;
1440 int j,k;
1441
1442 res = libusb_get_device_descriptor(usb_dev, &desc);
1443 if (res < 0)
1444 continue;
1445
1446 res = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
1447 if (res < 0)
1448 libusb_get_config_descriptor(usb_dev, 0, &conf_desc);
1449 if (!conf_desc)
1450 continue;
1451
1452 for (j = 0; j < conf_desc->bNumInterfaces && !good_open; j++) {
1453 const struct libusb_interface *intf = &conf_desc->interface[j];
1454 for (k = 0; k < intf->num_altsetting && !good_open; k++) {
1455 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1456 if (should_enumerate_interface(desc.idVendor, intf_desc)) {
1457 char dev_path[64];
1458 get_path(&dev_path, usb_dev, conf_desc->bConfigurationValue, intf_desc->bInterfaceNumber);
1459 if (!strcmp(dev_path, path)) {
1460 /* Matched Paths. Open this device */
1461
1462 /* OPEN HERE */
1463 res = libusb_open(usb_dev, &dev->device_handle);
1464 if (res < 0) {
1465 LOG("can't open device\n");
1466 break;
1467 }
1468 good_open = hidapi_initialize_device(dev, intf_desc, conf_desc);
1469 if (!good_open)
1470 libusb_close(dev->device_handle);
1471 }
1472 }
1473 }
1474 }
1475 libusb_free_config_descriptor(conf_desc);
1476 }
1477
1478 libusb_free_device_list(devs, 1);
1479
1480 /* If we have a good handle, return it. */
1481 if (good_open) {
1482 return dev;
1483 }
1484 else {
1485 /* Unable to open any devices. */
1486 free_hid_device(dev);
1487 return NULL;
1488 }
1489}
1490
1491
1492HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys_dev, int interface_num)
1493{
1494/* 0x01000107 is a LIBUSB_API_VERSION for 1.0.23 - version when libusb_wrap_sys_device was introduced */
1495#if (!defined(HIDAPI_TARGET_LIBUSB_API_VERSION) || HIDAPI_TARGET_LIBUSB_API_VERSION >= 0x01000107) && (LIBUSB_API_VERSION >= 0x01000107)
1496 hid_device *dev = NULL;
1497 struct libusb_config_descriptor *conf_desc = NULL;
1498 const struct libusb_interface_descriptor *selected_intf_desc = NULL;
1499 int res = 0;
1500 int j = 0, k = 0;
1501
1502 if(hid_init() < 0)
1503 return NULL;
1504
1505 dev = new_hid_device();
1506
1507 res = libusb_wrap_sys_device(usb_context, sys_dev, &dev->device_handle);
1508 if (res < 0) {
1509 LOG("libusb_wrap_sys_device failed: %d %s\n", res, libusb_error_name(res));
1510 goto err;
1511 }
1512
1513 res = libusb_get_active_config_descriptor(libusb_get_device(dev->device_handle), &conf_desc);
1514 if (res < 0)
1515 libusb_get_config_descriptor(libusb_get_device(dev->device_handle), 0, &conf_desc);
1516
1517 if (!conf_desc) {
1518 LOG("Failed to get configuration descriptor: %d %s\n", res, libusb_error_name(res));
1519 goto err;
1520 }
1521
1522 /* find matching HID interface */
1523 for (j = 0; j < conf_desc->bNumInterfaces && !selected_intf_desc; j++) {
1524 const struct libusb_interface *intf = &conf_desc->interface[j];
1525 for (k = 0; k < intf->num_altsetting; k++) {
1526 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1527 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
1528 if (interface_num < 0 || interface_num == intf_desc->bInterfaceNumber) {
1529 selected_intf_desc = intf_desc;
1530 break;
1531 }
1532 }
1533 }
1534 }
1535
1536 if (!selected_intf_desc) {
1537 if (interface_num < 0) {
1538 LOG("Sys USB device doesn't contain a HID interface\n");
1539 }
1540 else {
1541 LOG("Sys USB device doesn't contain a HID interface with number %d\n", interface_num);
1542 }
1543 goto err;
1544 }
1545
1546 if (!hidapi_initialize_device(dev, selected_intf_desc, conf_desc))
1547 goto err;
1548
1549 return dev;
1550
1551err:
1552 if (conf_desc)
1553 libusb_free_config_descriptor(conf_desc);
1554 if (dev->device_handle)
1555 libusb_close(dev->device_handle);
1556 free_hid_device(dev);
1557#else
1558 (void)sys_dev;
1559 (void)interface_num;
1560 LOG("libusb_wrap_sys_device is not available\n");
1561#endif
1562 return NULL;
1563}
1564
1565
1566int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
1567{
1568 int res;
1569 int report_number;
1570 int skipped_report_id = 0;
1571
1572 if (!data || (length ==0)) {
1573 return -1;
1574 }
1575
1576 report_number = data[0];
1577
1578 if ((!dev->no_skip_output_report_id && report_number == 0x0) || dev->skip_output_report_id) {
1579 data++;
1580 length--;
1581 skipped_report_id = 1;
1582 }
1583
1584
1585 if (dev->output_endpoint <= 0 || dev->no_output_reports_on_intr_ep) {
1586 /* No interrupt out endpoint. Use the Control Endpoint */
1587 res = libusb_control_transfer(dev->device_handle,
1588 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1589 0x09/*HID Set_Report*/,
1590 (2/*HID output*/ << 8) | report_number,
1591 dev->interface,
1592 (unsigned char *)data, (uint16_t)length,
1593 1000/*timeout millis*/);
1594
1595 if (res < 0)
1596 return -1;
1597
1598 if (skipped_report_id)
1599 length++;
1600
1601 return (int) length;
1602 }
1603 else {
1604 /* Use the interrupt out endpoint */
1605 int actual_length;
1606 res = libusb_interrupt_transfer(dev->device_handle,
1607 dev->output_endpoint,
1608 (unsigned char*)data,
1609 (int) length,
1610 &actual_length, 1000);
1611
1612 if (res < 0)
1613 return -1;
1614
1615 if (skipped_report_id)
1616 actual_length++;
1617
1618 return actual_length;
1619 }
1620}
1621
1622/* Helper function, to simplify hid_read().
1623 This should be called with dev->mutex locked. */
1624static int return_data(hid_device *dev, unsigned char *data, size_t length)
1625{
1626 /* Copy the data out of the linked list item (rpt) into the
1627 return buffer (data), and delete the liked list item. */
1628 struct input_report *rpt = dev->input_reports;
1629 size_t len = (length < rpt->len)? length: rpt->len;
1630 if (len > 0)
1631 memcpy(data, rpt->data, len);
1632 dev->input_reports = rpt->next;
1633 free(rpt->data);
1634 free(rpt);
1635 return (int) len;
1636}
1637
1638static void cleanup_mutex(void *param)
1639{
1640 hid_device *dev = param;
1641 hidapi_thread_mutex_unlock(&dev->thread_state);
1642}
1643
1644
1645int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1646{
1647#if 0
1648 int transferred;
1649 int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000);
1650 LOG("transferred: %d\n", transferred);
1651 return transferred;
1652#endif
1653 /* by initialising this variable right here, GCC gives a compilation warning/error: */
1654 /* error: variable ‘bytes_read’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] */
1655 int bytes_read; /* = -1; */
1656
1657 hidapi_thread_mutex_lock(&dev->thread_state);
1658 hidapi_thread_cleanup_push(cleanup_mutex, dev);
1659
1660 bytes_read = -1;
1661
1662 /* There's an input report queued up. Return it. */
1663 if (dev->input_reports) {
1664 /* Return the first one */
1665 bytes_read = return_data(dev, data, length);
1666 goto ret;
1667 }
1668
1669 if (dev->shutdown_thread) {
1670 /* This means the device has been disconnected.
1671 An error code of -1 should be returned. */
1672 bytes_read = -1;
1673 goto ret;
1674 }
1675
1676 if (milliseconds == -1) {
1677 /* Blocking */
1678 while (!dev->input_reports && !dev->shutdown_thread) {
1679 hidapi_thread_cond_wait(&dev->thread_state);
1680 }
1681 if (dev->input_reports) {
1682 bytes_read = return_data(dev, data, length);
1683 }
1684 }
1685 else if (milliseconds > 0) {
1686 /* Non-blocking, but called with timeout. */
1687 int res;
1688 hidapi_timespec ts;
1689 hidapi_thread_gettime(&ts);
1690 hidapi_thread_addtime(&ts, milliseconds);
1691
1692 while (!dev->input_reports && !dev->shutdown_thread) {
1693 res = hidapi_thread_cond_timedwait(&dev->thread_state, &ts);
1694 if (res == 0) {
1695 if (dev->input_reports) {
1696 bytes_read = return_data(dev, data, length);
1697 break;
1698 }
1699
1700 /* If we're here, there was a spurious wake up
1701 or the read thread was shutdown. Run the
1702 loop again (ie: don't break). */
1703 }
1704 else if (res == HIDAPI_THREAD_TIMED_OUT) {
1705 /* Timed out. */
1706 bytes_read = 0;
1707 break;
1708 }
1709 else {
1710 /* Error. */
1711 bytes_read = -1;
1712 break;
1713 }
1714 }
1715 }
1716 else {
1717 /* Purely non-blocking */
1718 bytes_read = 0;
1719 }
1720
1721ret:
1722 hidapi_thread_mutex_unlock(&dev->thread_state);
1723 hidapi_thread_cleanup_pop(0);
1724
1725 return bytes_read;
1726}
1727
1728int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
1729{
1730 return hid_read_timeout(dev, data, length, dev->blocking ? -1 : 0);
1731}
1732
1733int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
1734{
1735 dev->blocking = !nonblock;
1736
1737 return 0;
1738}
1739
1740
1741int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
1742{
1743 int res = -1;
1744 int skipped_report_id = 0;
1745 int report_number = data[0];
1746
1747 if (report_number == 0x0) {
1748 data++;
1749 length--;
1750 skipped_report_id = 1;
1751 }
1752
1753 res = libusb_control_transfer(dev->device_handle,
1754 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1755 0x09/*HID set_report*/,
1756 (3/*HID feature*/ << 8) | report_number,
1757 dev->interface,
1758 (unsigned char *)data, (uint16_t)length,
1759 1000/*timeout millis*/);
1760
1761 if (res < 0)
1762 return -1;
1763
1764 /* Account for the report ID */
1765 if (skipped_report_id)
1766 length++;
1767
1768 return (int) length;
1769}
1770
1771int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
1772{
1773 int res = -1;
1774 int skipped_report_id = 0;
1775 int report_number = data[0];
1776
1777 if (report_number == 0x0) {
1778 /* Offset the return buffer by 1, so that the report ID
1779 will remain in byte 0. */
1780 data++;
1781 length--;
1782 skipped_report_id = 1;
1783 }
1784 res = libusb_control_transfer(dev->device_handle,
1785 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
1786 0x01/*HID get_report*/,
1787 (3/*HID feature*/ << 8) | report_number,
1788 dev->interface,
1789 (unsigned char *)data, (uint16_t)length,
1790 1000/*timeout millis*/);
1791
1792 if (res < 0)
1793 return -1;
1794
1795 if (skipped_report_id)
1796 res++;
1797
1798 return res;
1799}
1800
1801int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
1802{
1803 int res = -1;
1804 int skipped_report_id = 0;
1805 int report_number = data[0];
1806
1807 if (report_number == 0x0) {
1808 /* Offset the return buffer by 1, so that the report ID
1809 will remain in byte 0. */
1810 data++;
1811 length--;
1812 skipped_report_id = 1;
1813 }
1814 res = libusb_control_transfer(dev->device_handle,
1815 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
1816 0x01/*HID get_report*/,
1817 (1/*HID Input*/ << 8) | report_number,
1818 dev->interface,
1819 (unsigned char *)data, (uint16_t)length,
1820 1000/*timeout millis*/);
1821
1822 if (res < 0)
1823 return -1;
1824
1825 if (skipped_report_id)
1826 res++;
1827
1828 return res;
1829}
1830
1831void HID_API_EXPORT hid_close(hid_device *dev)
1832{
1833 if (!dev)
1834 return;
1835
1836 /* Cause read_thread() to stop. */
1837 dev->shutdown_thread = 1;
1838 libusb_cancel_transfer(dev->transfer);
1839
1840 /* Wait for read_thread() to end. */
1841 hidapi_thread_join(&dev->thread_state);
1842
1843 /* Clean up the Transfer objects allocated in read_thread(). */
1844 free(dev->transfer->buffer);
1845 dev->transfer->buffer = NULL;
1846 libusb_free_transfer(dev->transfer);
1847
1848 /* release the interface */
1849 libusb_release_interface(dev->device_handle, dev->interface);
1850
1851 /* reattach the kernel driver if it was detached */
1852#ifdef DETACH_KERNEL_DRIVER
1853 if (dev->is_driver_detached) {
1854 int res = libusb_attach_kernel_driver(dev->device_handle, dev->interface);
1855 if (res < 0)
1856 LOG("Failed to reattach the driver to kernel.\n");
1857 }
1858#endif
1859
1860 /* Close the handle */
1861 libusb_close(dev->device_handle);
1862
1863 /* Clear out the queue of received reports. */
1864 hidapi_thread_mutex_lock(&dev->thread_state);
1865 while (dev->input_reports) {
1866 return_data(dev, NULL, 0);
1867 }
1868 hidapi_thread_mutex_unlock(&dev->thread_state);
1869
1870 free_hid_device(dev);
1871}
1872
1873
1874int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
1875{
1876 return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen);
1877}
1878
1879int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
1880{
1881 return hid_get_indexed_string(dev, dev->product_index, string, maxlen);
1882}
1883
1884int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1885{
1886 return hid_get_indexed_string(dev, dev->serial_index, string, maxlen);
1887}
1888
1889HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_device *dev) {
1890 if (!dev->device_info) {
1891 struct libusb_device_descriptor desc;
1892 libusb_device *usb_device = libusb_get_device(dev->device_handle);
1893 libusb_get_device_descriptor(usb_device, &desc);
1894
1895 dev->device_info = create_device_info_for_device(usb_device, dev->device_handle, &desc, dev->config_number, dev->interface, dev->interface_class, dev->interface_subclass, dev->interface_protocol);
1896 // device error already set by create_device_info_for_device, if any
1897
1898 if (dev->device_info) {
1899 fill_device_info_usage(dev->device_info, dev->device_handle, dev->interface, dev->report_descriptor_size);
1900 }
1901 }
1902
1903 return dev->device_info;
1904}
1905
1906int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1907{
1908 wchar_t *str;
1909
1910 str = get_usb_string(dev->device_handle, string_index);
1911 if (str) {
1912 wcsncpy(string, str, maxlen);
1913 string[maxlen-1] = L'\0';
1914 free(str);
1915 return 0;
1916 }
1917 else
1918 return -1;
1919}
1920
1921
1922int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
1923{
1924 return hid_get_report_descriptor_libusb(dev->device_handle, dev->interface, dev->report_descriptor_size, buf, buf_size);
1925}
1926
1927
1928HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
1929{
1930 (void)dev;
1931 return L"hid_error is not implemented yet";
1932}
1933
1934
1935struct lang_map_entry {
1936 const char *name;
1937 const char *string_code;
1938 uint16_t usb_code;
1939};
1940
1941#define LANG(name,code,usb_code) { name, code, usb_code }
1942static struct lang_map_entry lang_map[] = {
1943 LANG("Afrikaans", "af", 0x0436),
1944 LANG("Albanian", "sq", 0x041C),
1945 LANG("Arabic - United Arab Emirates", "ar_ae", 0x3801),
1946 LANG("Arabic - Bahrain", "ar_bh", 0x3C01),
1947 LANG("Arabic - Algeria", "ar_dz", 0x1401),
1948 LANG("Arabic - Egypt", "ar_eg", 0x0C01),
1949 LANG("Arabic - Iraq", "ar_iq", 0x0801),
1950 LANG("Arabic - Jordan", "ar_jo", 0x2C01),
1951 LANG("Arabic - Kuwait", "ar_kw", 0x3401),
1952 LANG("Arabic - Lebanon", "ar_lb", 0x3001),
1953 LANG("Arabic - Libya", "ar_ly", 0x1001),
1954 LANG("Arabic - Morocco", "ar_ma", 0x1801),
1955 LANG("Arabic - Oman", "ar_om", 0x2001),
1956 LANG("Arabic - Qatar", "ar_qa", 0x4001),
1957 LANG("Arabic - Saudi Arabia", "ar_sa", 0x0401),
1958 LANG("Arabic - Syria", "ar_sy", 0x2801),
1959 LANG("Arabic - Tunisia", "ar_tn", 0x1C01),
1960 LANG("Arabic - Yemen", "ar_ye", 0x2401),
1961 LANG("Armenian", "hy", 0x042B),
1962 LANG("Azeri - Latin", "az_az", 0x042C),
1963 LANG("Azeri - Cyrillic", "az_az", 0x082C),
1964 LANG("Basque", "eu", 0x042D),
1965 LANG("Belarusian", "be", 0x0423),
1966 LANG("Bulgarian", "bg", 0x0402),
1967 LANG("Catalan", "ca", 0x0403),
1968 LANG("Chinese - China", "zh_cn", 0x0804),
1969 LANG("Chinese - Hong Kong SAR", "zh_hk", 0x0C04),
1970 LANG("Chinese - Macau SAR", "zh_mo", 0x1404),
1971 LANG("Chinese - Singapore", "zh_sg", 0x1004),
1972 LANG("Chinese - Taiwan", "zh_tw", 0x0404),
1973 LANG("Croatian", "hr", 0x041A),
1974 LANG("Czech", "cs", 0x0405),
1975 LANG("Danish", "da", 0x0406),
1976 LANG("Dutch - Netherlands", "nl_nl", 0x0413),
1977 LANG("Dutch - Belgium", "nl_be", 0x0813),
1978 LANG("English - Australia", "en_au", 0x0C09),
1979 LANG("English - Belize", "en_bz", 0x2809),
1980 LANG("English - Canada", "en_ca", 0x1009),
1981 LANG("English - Caribbean", "en_cb", 0x2409),
1982 LANG("English - Ireland", "en_ie", 0x1809),
1983 LANG("English - Jamaica", "en_jm", 0x2009),
1984 LANG("English - New Zealand", "en_nz", 0x1409),
1985 LANG("English - Philippines", "en_ph", 0x3409),
1986 LANG("English - Southern Africa", "en_za", 0x1C09),
1987 LANG("English - Trinidad", "en_tt", 0x2C09),
1988 LANG("English - Great Britain", "en_gb", 0x0809),
1989 LANG("English - United States", "en_us", 0x0409),
1990 LANG("Estonian", "et", 0x0425),
1991 LANG("Farsi", "fa", 0x0429),
1992 LANG("Finnish", "fi", 0x040B),
1993 LANG("Faroese", "fo", 0x0438),
1994 LANG("French - France", "fr_fr", 0x040C),
1995 LANG("French - Belgium", "fr_be", 0x080C),
1996 LANG("French - Canada", "fr_ca", 0x0C0C),
1997 LANG("French - Luxembourg", "fr_lu", 0x140C),
1998 LANG("French - Switzerland", "fr_ch", 0x100C),
1999 LANG("Gaelic - Ireland", "gd_ie", 0x083C),
2000 LANG("Gaelic - Scotland", "gd", 0x043C),
2001 LANG("German - Germany", "de_de", 0x0407),
2002 LANG("German - Austria", "de_at", 0x0C07),
2003 LANG("German - Liechtenstein", "de_li", 0x1407),
2004 LANG("German - Luxembourg", "de_lu", 0x1007),
2005 LANG("German - Switzerland", "de_ch", 0x0807),
2006 LANG("Greek", "el", 0x0408),
2007 LANG("Hebrew", "he", 0x040D),
2008 LANG("Hindi", "hi", 0x0439),
2009 LANG("Hungarian", "hu", 0x040E),
2010 LANG("Icelandic", "is", 0x040F),
2011 LANG("Indonesian", "id", 0x0421),
2012 LANG("Italian - Italy", "it_it", 0x0410),
2013 LANG("Italian - Switzerland", "it_ch", 0x0810),
2014 LANG("Japanese", "ja", 0x0411),
2015 LANG("Korean", "ko", 0x0412),
2016 LANG("Latvian", "lv", 0x0426),
2017 LANG("Lithuanian", "lt", 0x0427),
2018 LANG("F.Y.R.O. Macedonia", "mk", 0x042F),
2019 LANG("Malay - Malaysia", "ms_my", 0x043E),
2020 LANG("Malay – Brunei", "ms_bn", 0x083E),
2021 LANG("Maltese", "mt", 0x043A),
2022 LANG("Marathi", "mr", 0x044E),
2023 LANG("Norwegian - Bokml", "no_no", 0x0414),
2024 LANG("Norwegian - Nynorsk", "no_no", 0x0814),
2025 LANG("Polish", "pl", 0x0415),
2026 LANG("Portuguese - Portugal", "pt_pt", 0x0816),
2027 LANG("Portuguese - Brazil", "pt_br", 0x0416),
2028 LANG("Raeto-Romance", "rm", 0x0417),
2029 LANG("Romanian - Romania", "ro", 0x0418),
2030 LANG("Romanian - Republic of Moldova", "ro_mo", 0x0818),
2031 LANG("Russian", "ru", 0x0419),
2032 LANG("Russian - Republic of Moldova", "ru_mo", 0x0819),
2033 LANG("Sanskrit", "sa", 0x044F),
2034 LANG("Serbian - Cyrillic", "sr_sp", 0x0C1A),
2035 LANG("Serbian - Latin", "sr_sp", 0x081A),
2036 LANG("Setsuana", "tn", 0x0432),
2037 LANG("Slovenian", "sl", 0x0424),
2038 LANG("Slovak", "sk", 0x041B),
2039 LANG("Sorbian", "sb", 0x042E),
2040 LANG("Spanish - Spain (Traditional)", "es_es", 0x040A),
2041 LANG("Spanish - Argentina", "es_ar", 0x2C0A),
2042 LANG("Spanish - Bolivia", "es_bo", 0x400A),
2043 LANG("Spanish - Chile", "es_cl", 0x340A),
2044 LANG("Spanish - Colombia", "es_co", 0x240A),
2045 LANG("Spanish - Costa Rica", "es_cr", 0x140A),
2046 LANG("Spanish - Dominican Republic", "es_do", 0x1C0A),
2047 LANG("Spanish - Ecuador", "es_ec", 0x300A),
2048 LANG("Spanish - Guatemala", "es_gt", 0x100A),
2049 LANG("Spanish - Honduras", "es_hn", 0x480A),
2050 LANG("Spanish - Mexico", "es_mx", 0x080A),
2051 LANG("Spanish - Nicaragua", "es_ni", 0x4C0A),
2052 LANG("Spanish - Panama", "es_pa", 0x180A),
2053 LANG("Spanish - Peru", "es_pe", 0x280A),
2054 LANG("Spanish - Puerto Rico", "es_pr", 0x500A),
2055 LANG("Spanish - Paraguay", "es_py", 0x3C0A),
2056 LANG("Spanish - El Salvador", "es_sv", 0x440A),
2057 LANG("Spanish - Uruguay", "es_uy", 0x380A),
2058 LANG("Spanish - Venezuela", "es_ve", 0x200A),
2059 LANG("Southern Sotho", "st", 0x0430),
2060 LANG("Swahili", "sw", 0x0441),
2061 LANG("Swedish - Sweden", "sv_se", 0x041D),
2062 LANG("Swedish - Finland", "sv_fi", 0x081D),
2063 LANG("Tamil", "ta", 0x0449),
2064 LANG("Tatar", "tt", 0X0444),
2065 LANG("Thai", "th", 0x041E),
2066 LANG("Turkish", "tr", 0x041F),
2067 LANG("Tsonga", "ts", 0x0431),
2068 LANG("Ukrainian", "uk", 0x0422),
2069 LANG("Urdu", "ur", 0x0420),
2070 LANG("Uzbek - Cyrillic", "uz_uz", 0x0843),
2071 LANG("Uzbek – Latin", "uz_uz", 0x0443),
2072 LANG("Vietnamese", "vi", 0x042A),
2073 LANG("Xhosa", "xh", 0x0434),
2074 LANG("Yiddish", "yi", 0x043D),
2075 LANG("Zulu", "zu", 0x0435),
2076 LANG(NULL, NULL, 0x0),
2077};
2078
2079uint16_t get_usb_code_for_current_locale(void)
2080{
2081 char *locale;
2082 char search_string[64];
2083 char *ptr;
2084 struct lang_map_entry *lang;
2085
2086 /* Get the current locale. */
2087 locale = setlocale(0, NULL);
2088 if (!locale)
2089 return 0x0;
2090
2091 /* Make a copy of the current locale string. */
2092 strncpy(search_string, locale, sizeof(search_string)-1);
2093 search_string[sizeof(search_string)-1] = '\0';
2094
2095 /* Chop off the encoding part, and make it lower case. */
2096 ptr = search_string;
2097 while (*ptr) {
2098 *ptr = tolower(*ptr);
2099 if (*ptr == '.') {
2100 *ptr = '\0';
2101 break;
2102 }
2103 ptr++;
2104 }
2105
2106 /* Find the entry which matches the string code of our locale. */
2107 lang = lang_map;
2108 while (lang->string_code) {
2109 if (!strcmp(lang->string_code, search_string)) {
2110 return lang->usb_code;
2111 }
2112 lang++;
2113 }
2114
2115 /* There was no match. Find with just the language only. */
2116 /* Chop off the variant. Chop it off at the '_'. */
2117 ptr = search_string;
2118 while (*ptr) {
2119 *ptr = tolower(*ptr);
2120 if (*ptr == '_') {
2121 *ptr = '\0';
2122 break;
2123 }
2124 ptr++;
2125 }
2126
2127#if 0 /* TODO: Do we need this? */
2128 /* Find the entry which matches the string code of our language. */
2129 lang = lang_map;
2130 while (lang->string_code) {
2131 if (!strcmp(lang->string_code, search_string)) {
2132 return lang->usb_code;
2133 }
2134 lang++;
2135 }
2136#endif
2137
2138 /* Found nothing. */
2139 return 0x0;
2140}
2141
2142#ifdef __cplusplus
2143}
2144#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_libusb.h b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_libusb.h
new file mode 100644
index 0000000..758f16f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_libusb.h
@@ -0,0 +1,56 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2021, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19
20/** @file
21 * @defgroup API hidapi API
22
23 * Since version 0.11.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 11, 0).
24 */
25
26#ifndef HIDAPI_LIBUSB_H__
27#define HIDAPI_LIBUSB_H__
28
29#include <stdint.h>
30
31#include "../hidapi/hidapi.h"
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37 /** @brief Open a HID device using libusb_wrap_sys_device.
38 See https://libusb.sourceforge.io/api-1.0/group__libusb__dev.html#ga98f783e115ceff4eaf88a60e6439563c,
39 for details on libusb_wrap_sys_device.
40
41 @ingroup API
42 @param sys_dev Platform-specific file descriptor that can be recognised by libusb.
43 @param interface_num USB interface number of the device to be used as HID interface.
44 Pass -1 to select first HID interface of the device.
45
46 @returns
47 This function returns a pointer to a #hid_device object on
48 success or NULL on failure.
49 */
50 HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys_dev, int interface_num);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h
new file mode 100644
index 0000000..0abe733
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h
@@ -0,0 +1,174 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Sam Lantinga
11
12 Copyright 2023, All Rights Reserved.
13
14 At the discretion of the user of this library,
15 this software may be licensed under the terms of the
16 GNU General Public License v3, a BSD-Style license, or the
17 original HIDAPI license as outlined in the LICENSE.txt,
18 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
19 files located at the root of the source distribution.
20 These files may also be found in the public source
21 code repository located at:
22 https://github.com/libusb/hidapi .
23********************************************************/
24
25#include <pthread.h>
26
27#if defined(__ANDROID__) && __ANDROID_API__ < __ANDROID_API_N__
28
29/* Barrier implementation because Android/Bionic don't have pthread_barrier.
30 This implementation came from Brent Priddy and was posted on
31 StackOverflow. It is used with his permission. */
32typedef int pthread_barrierattr_t;
33typedef struct pthread_barrier {
34 pthread_mutex_t mutex;
35 pthread_cond_t cond;
36 int count;
37 int trip_count;
38} pthread_barrier_t;
39
40static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
41{
42 if(count == 0) {
43 errno = EINVAL;
44 return -1;
45 }
46
47 if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
48 return -1;
49 }
50 if(pthread_cond_init(&barrier->cond, 0) < 0) {
51 pthread_mutex_destroy(&barrier->mutex);
52 return -1;
53 }
54 barrier->trip_count = count;
55 barrier->count = 0;
56
57 return 0;
58}
59
60static int pthread_barrier_destroy(pthread_barrier_t *barrier)
61{
62 pthread_cond_destroy(&barrier->cond);
63 pthread_mutex_destroy(&barrier->mutex);
64 return 0;
65}
66
67static int pthread_barrier_wait(pthread_barrier_t *barrier)
68{
69 pthread_mutex_lock(&barrier->mutex);
70 ++(barrier->count);
71 if(barrier->count >= barrier->trip_count) {
72 barrier->count = 0;
73 pthread_cond_broadcast(&barrier->cond);
74 pthread_mutex_unlock(&barrier->mutex);
75 return 1;
76 }
77 else {
78 pthread_cond_wait(&barrier->cond, &(barrier->mutex));
79 pthread_mutex_unlock(&barrier->mutex);
80 return 0;
81 }
82}
83
84#endif
85
86#define HIDAPI_THREAD_TIMED_OUT ETIMEDOUT
87
88typedef struct timespec hidapi_timespec;
89
90typedef struct
91{
92 pthread_t thread;
93 pthread_mutex_t mutex; /* Protects input_reports */
94 pthread_cond_t condition;
95 pthread_barrier_t barrier; /* Ensures correct startup sequence */
96
97} hidapi_thread_state;
98
99static void hidapi_thread_state_init(hidapi_thread_state *state)
100{
101 pthread_mutex_init(&state->mutex, NULL);
102 pthread_cond_init(&state->condition, NULL);
103 pthread_barrier_init(&state->barrier, NULL, 2);
104}
105
106static void hidapi_thread_state_destroy(hidapi_thread_state *state)
107{
108 pthread_barrier_destroy(&state->barrier);
109 pthread_cond_destroy(&state->condition);
110 pthread_mutex_destroy(&state->mutex);
111}
112
113#define hidapi_thread_cleanup_push pthread_cleanup_push
114#define hidapi_thread_cleanup_pop pthread_cleanup_pop
115
116static void hidapi_thread_mutex_lock(hidapi_thread_state *state)
117{
118 pthread_mutex_lock(&state->mutex);
119}
120
121static void hidapi_thread_mutex_unlock(hidapi_thread_state *state)
122{
123 pthread_mutex_unlock(&state->mutex);
124}
125
126static void hidapi_thread_cond_wait(hidapi_thread_state *state)
127{
128 pthread_cond_wait(&state->condition, &state->mutex);
129}
130
131static int hidapi_thread_cond_timedwait(hidapi_thread_state *state, hidapi_timespec *ts)
132{
133 return pthread_cond_timedwait(&state->condition, &state->mutex, ts);
134}
135
136static void hidapi_thread_cond_signal(hidapi_thread_state *state)
137{
138 pthread_cond_signal(&state->condition);
139}
140
141static void hidapi_thread_cond_broadcast(hidapi_thread_state *state)
142{
143 pthread_cond_broadcast(&state->condition);
144}
145
146static void hidapi_thread_barrier_wait(hidapi_thread_state *state)
147{
148 pthread_barrier_wait(&state->barrier);
149}
150
151static void hidapi_thread_create(hidapi_thread_state *state, void *(*func)(void*), void *func_arg)
152{
153 pthread_create(&state->thread, NULL, func, func_arg);
154}
155
156static void hidapi_thread_join(hidapi_thread_state *state)
157{
158 pthread_join(state->thread, NULL);
159}
160
161static void hidapi_thread_gettime(hidapi_timespec *ts)
162{
163 clock_gettime(CLOCK_REALTIME, ts);
164}
165
166static void hidapi_thread_addtime(hidapi_timespec *ts, int milliseconds)
167{
168 ts->tv_sec += milliseconds / 1000;
169 ts->tv_nsec += (milliseconds % 1000) * 1000000;
170 if (ts->tv_nsec >= 1000000000L) {
171 ts->tv_sec++;
172 ts->tv_nsec -= 1000000000L;
173 }
174}
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h
new file mode 100644
index 0000000..1f5c7db
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h
@@ -0,0 +1,202 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/* Barrier implementation because Android/Bionic don't have pthread_barrier.
23 This implementation came from Brent Priddy and was posted on
24 StackOverflow. It is used with his permission. */
25
26typedef struct _SDL_ThreadBarrier
27{
28 SDL_Mutex *mutex;
29 SDL_Condition *cond;
30 Uint32 count;
31 Uint32 trip_count;
32} SDL_ThreadBarrier;
33
34static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count)
35{
36 SDL_assert(barrier != NULL);
37 SDL_assert(count != 0);
38
39 barrier->mutex = SDL_CreateMutex();
40 if (barrier->mutex == NULL) {
41 return -1; /* Error set by CreateMutex */
42 }
43 barrier->cond = SDL_CreateCondition();
44 if (barrier->cond == NULL) {
45 return -1; /* Error set by CreateCond */
46 }
47
48 barrier->trip_count = count;
49 barrier->count = 0;
50
51 return 0;
52}
53
54static void SDL_DestroyThreadBarrier(SDL_ThreadBarrier *barrier)
55{
56 SDL_DestroyCondition(barrier->cond);
57 SDL_DestroyMutex(barrier->mutex);
58}
59
60static int SDL_WaitThreadBarrier(SDL_ThreadBarrier *barrier)
61{
62 SDL_LockMutex(barrier->mutex);
63 barrier->count += 1;
64 if (barrier->count >= barrier->trip_count) {
65 barrier->count = 0;
66 SDL_BroadcastCondition(barrier->cond);
67 SDL_UnlockMutex(barrier->mutex);
68 return 1;
69 }
70 SDL_WaitCondition(barrier->cond, barrier->mutex);
71 SDL_UnlockMutex(barrier->mutex);
72 return 0;
73}
74
75#include "../../thread/SDL_systhread.h"
76
77#define HIDAPI_THREAD_TIMED_OUT 1
78
79typedef Uint64 hidapi_timespec;
80
81typedef struct
82{
83 SDL_Thread *thread;
84 SDL_Mutex *mutex; /* Protects input_reports */
85 SDL_Condition *condition;
86 SDL_ThreadBarrier barrier; /* Ensures correct startup sequence */
87
88} hidapi_thread_state;
89
90static void hidapi_thread_state_init(hidapi_thread_state *state)
91{
92 state->mutex = SDL_CreateMutex();
93 state->condition = SDL_CreateCondition();
94 SDL_CreateThreadBarrier(&state->barrier, 2);
95}
96
97static void hidapi_thread_state_destroy(hidapi_thread_state *state)
98{
99 SDL_DestroyThreadBarrier(&state->barrier);
100 SDL_DestroyCondition(state->condition);
101 SDL_DestroyMutex(state->mutex);
102}
103
104static void hidapi_thread_cleanup_push(void (*routine)(void *), void *arg)
105{
106 /* There isn't an equivalent in SDL, and it's only useful for threads calling hid_read_timeout() */
107}
108
109static void hidapi_thread_cleanup_pop(int execute)
110{
111}
112
113static void hidapi_thread_mutex_lock(hidapi_thread_state *state)
114{
115 SDL_LockMutex(state->mutex);
116}
117
118static void hidapi_thread_mutex_unlock(hidapi_thread_state *state)
119{
120 SDL_UnlockMutex(state->mutex);
121}
122
123static void hidapi_thread_cond_wait(hidapi_thread_state *state)
124{
125 SDL_WaitCondition(state->condition, state->mutex);
126}
127
128static int hidapi_thread_cond_timedwait(hidapi_thread_state *state, hidapi_timespec *ts)
129{
130 Sint64 timeout_ns;
131 Sint32 timeout_ms;
132
133 timeout_ns = (Sint64)(*ts - SDL_GetTicksNS());
134 if (timeout_ns <= 0) {
135 timeout_ms = 0;
136 } else {
137 timeout_ms = (Sint32)SDL_NS_TO_MS(timeout_ns);
138 }
139 if (SDL_WaitConditionTimeout(state->condition, state->mutex, timeout_ms)) {
140 return 0;
141 } else {
142 return HIDAPI_THREAD_TIMED_OUT;
143 }
144}
145
146static void hidapi_thread_cond_signal(hidapi_thread_state *state)
147{
148 SDL_SignalCondition(state->condition);
149}
150
151static void hidapi_thread_cond_broadcast(hidapi_thread_state *state)
152{
153 SDL_BroadcastCondition(state->condition);
154}
155
156static void hidapi_thread_barrier_wait(hidapi_thread_state *state)
157{
158 SDL_WaitThreadBarrier(&state->barrier);
159}
160
161typedef struct
162{
163 void *(*func)(void*);
164 void *func_arg;
165
166} RunInputThreadParam;
167
168static int RunInputThread(void *param)
169{
170 RunInputThreadParam *data = (RunInputThreadParam *)param;
171 void *(*func)(void*) = data->func;
172 void *func_arg = data->func_arg;
173 SDL_free(data);
174 func(func_arg);
175 return 0;
176}
177
178static void hidapi_thread_create(hidapi_thread_state *state, void *(*func)(void*), void *func_arg)
179{
180 RunInputThreadParam *param = (RunInputThreadParam *)malloc(sizeof(*param));
181 /* Note that the hidapi code didn't check for thread creation failure.
182 * We'll crash if malloc() fails
183 */
184 param->func = func;
185 param->func_arg = func_arg;
186 state->thread = SDL_CreateThread(RunInputThread, "libusb", param);
187}
188
189static void hidapi_thread_join(hidapi_thread_state *state)
190{
191 SDL_WaitThread(state->thread, NULL);
192}
193
194static void hidapi_thread_gettime(hidapi_timespec *ts)
195{
196 *ts = SDL_GetTicksNS();
197}
198
199static void hidapi_thread_addtime(hidapi_timespec *ts, int milliseconds)
200{
201 *ts += SDL_MS_TO_NS(milliseconds);
202}
diff --git a/contrib/SDL-3.2.8/src/hidapi/linux/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/linux/CMakeLists.txt
new file mode 100644
index 0000000..9c62708
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/linux/CMakeLists.txt
@@ -0,0 +1,38 @@
1cmake_minimum_required(VERSION 3.6.3...3.25 FATAL_ERROR)
2
3add_library(hidapi_hidraw
4 ${HIDAPI_PUBLIC_HEADERS}
5 hid.c
6)
7target_link_libraries(hidapi_hidraw PUBLIC hidapi_include)
8
9find_package(Threads REQUIRED)
10
11include(FindPkgConfig)
12pkg_check_modules(libudev REQUIRED IMPORTED_TARGET libudev)
13
14target_link_libraries(hidapi_hidraw PRIVATE PkgConfig::libudev Threads::Threads)
15
16set_target_properties(hidapi_hidraw
17 PROPERTIES
18 EXPORT_NAME "hidraw"
19 OUTPUT_NAME "hidapi-hidraw"
20 VERSION ${PROJECT_VERSION}
21 SOVERSION ${PROJECT_VERSION_MAJOR}
22 PUBLIC_HEADER "${HIDAPI_PUBLIC_HEADERS}"
23)
24
25# compatibility with find_package()
26add_library(hidapi::hidraw ALIAS hidapi_hidraw)
27# compatibility with raw library link
28add_library(hidapi-hidraw ALIAS hidapi_hidraw)
29
30if(HIDAPI_INSTALL_TARGETS)
31 install(TARGETS hidapi_hidraw EXPORT hidapi
32 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
33 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
34 PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/hidapi"
35 )
36endif()
37
38hidapi_configure_pc("${PROJECT_ROOT}/pc/hidapi-hidraw.pc.in")
diff --git a/contrib/SDL-3.2.8/src/hidapi/linux/Makefile-manual b/contrib/SDL-3.2.8/src/hidapi/linux/Makefile-manual
new file mode 100644
index 0000000..81d28cf
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/linux/Makefile-manual
@@ -0,0 +1,42 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: hidtest-hidraw libs
10
11libs: libhidapi-hidraw.so
12
13CC ?= gcc
14CFLAGS ?= -Wall -g -fpic
15
16LDFLAGS ?= -Wall -g
17
18
19COBJS = hid.o ../hidtest/test.o
20OBJS = $(COBJS)
21LIBS_UDEV = `pkg-config libudev --libs` -lrt
22LIBS = $(LIBS_UDEV)
23INCLUDES ?= -I../hidapi `pkg-config libusb-1.0 --cflags`
24
25
26# Console Test Program
27hidtest-hidraw: $(COBJS)
28 $(CC) $(LDFLAGS) $^ $(LIBS_UDEV) -o $@
29
30# Shared Libs
31libhidapi-hidraw.so: $(COBJS)
32 $(CC) $(LDFLAGS) $(LIBS_UDEV) -shared -fpic -Wl,-soname,$@.0 $^ -o $@
33
34# Objects
35$(COBJS): %.o: %.c
36 $(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@
37
38
39clean:
40 rm -f $(OBJS) hidtest-hidraw libhidapi-hidraw.so $(COBJS)
41
42.PHONY: clean libs
diff --git a/contrib/SDL-3.2.8/src/hidapi/linux/Makefile.am b/contrib/SDL-3.2.8/src/hidapi/linux/Makefile.am
new file mode 100644
index 0000000..230eeb7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/linux/Makefile.am
@@ -0,0 +1,10 @@
1lib_LTLIBRARIES = libhidapi-hidraw.la
2libhidapi_hidraw_la_SOURCES = hid.c
3libhidapi_hidraw_la_LDFLAGS = $(LTLDFLAGS)
4AM_CPPFLAGS = -I$(top_srcdir)/hidapi/ $(CFLAGS_HIDRAW)
5libhidapi_hidraw_la_LIBADD = $(LIBS_HIDRAW)
6
7hdrdir = $(includedir)/hidapi
8hdr_HEADERS = $(top_srcdir)/hidapi/hidapi.h
9
10EXTRA_DIST = Makefile-manual
diff --git a/contrib/SDL-3.2.8/src/hidapi/linux/hid.c b/contrib/SDL-3.2.8/src/hidapi/linux/hid.c
new file mode 100644
index 0000000..dbbb327
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/linux/hid.c
@@ -0,0 +1,1492 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Copyright 2022, All Rights Reserved.
11
12 At the discretion of the user of this library,
13 this software may be licensed under the terms of the
14 GNU General Public License v3, a BSD-Style license, or the
15 original HIDAPI license as outlined in the LICENSE.txt,
16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17 files located at the root of the source distribution.
18 These files may also be found in the public source
19 code repository located at:
20 https://github.com/libusb/hidapi .
21********************************************************/
22
23/* C */
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27#include <locale.h>
28#include <errno.h>
29
30/* Unix */
31#include <unistd.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/ioctl.h>
35#include <sys/utsname.h>
36#include <fcntl.h>
37#include <poll.h>
38
39/* Linux */
40#include <linux/hidraw.h>
41#include <linux/version.h>
42#include <linux/input.h>
43#include <libudev.h>
44
45#include "../hidapi/hidapi.h"
46
47#ifndef BUS_SPI
48#define BUS_SPI 0x1C
49#endif
50
51#ifdef HIDAPI_ALLOW_BUILD_WORKAROUND_KERNEL_2_6_39
52/* This definitions first appeared in Linux Kernel 2.6.39 in linux/hidraw.h.
53 hidapi doesn't support kernels older than that,
54 so we don't define macros below explicitly, to fail builds on old kernels.
55 For those who really need this as a workaround (e.g. to be able to build on old build machines),
56 can workaround by defining the macro above.
57*/
58#ifndef HIDIOCSFEATURE
59#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
60#endif
61#ifndef HIDIOCGFEATURE
62#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
63#endif
64
65#endif
66
67
68// HIDIOCGINPUT is not defined in Linux kernel headers < 5.11.
69// This definition is from hidraw.h in Linux >= 5.11.
70// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f43d3870cafa2a0f3854c1819c8385733db8f9ae
71#ifndef HIDIOCGINPUT
72#define HIDIOCGINPUT(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x0A, len)
73#endif
74
75struct hid_device_ {
76 int device_handle;
77 int blocking;
78 int needs_ble_hack;
79 wchar_t *last_error_str;
80 struct hid_device_info* device_info;
81};
82
83static struct hid_api_version api_version = {
84 .major = HID_API_VERSION_MAJOR,
85 .minor = HID_API_VERSION_MINOR,
86 .patch = HID_API_VERSION_PATCH
87};
88
89static wchar_t *last_global_error_str = NULL;
90
91
92static hid_device *new_hid_device(void)
93{
94 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
95 if (dev == NULL) {
96 return NULL;
97 }
98
99 dev->device_handle = -1;
100 dev->blocking = 1;
101 dev->last_error_str = NULL;
102 dev->device_info = NULL;
103
104 return dev;
105}
106
107
108/* The caller must free the returned string with free(). */
109static wchar_t *utf8_to_wchar_t(const char *utf8)
110{
111 wchar_t *ret = NULL;
112
113 if (utf8) {
114 size_t wlen = mbstowcs(NULL, utf8, 0);
115 if ((size_t) -1 == wlen) {
116 return wcsdup(L"");
117 }
118 ret = (wchar_t*) calloc(wlen+1, sizeof(wchar_t));
119 if (ret == NULL) {
120 /* as much as we can do at this point */
121 return NULL;
122 }
123 mbstowcs(ret, utf8, wlen+1);
124 ret[wlen] = 0x0000;
125 }
126
127 return ret;
128}
129
130
131/* Makes a copy of the given error message (and decoded according to the
132 * currently locale) into the wide string pointer pointed by error_str.
133 * The last stored error string is freed.
134 * Use register_error_str(NULL) to free the error message completely. */
135static void register_error_str(wchar_t **error_str, const char *msg)
136{
137 free(*error_str);
138#ifdef HIDAPI_USING_SDL_RUNTIME
139 /* Thread-safe error handling */
140 if (msg) {
141 SDL_SetError("%s", msg);
142 } else {
143 SDL_ClearError();
144 }
145#else
146 *error_str = utf8_to_wchar_t(msg);
147#endif
148}
149
150/* Semilar to register_error_str, but allows passing a format string with va_list args into this function. */
151static void register_error_str_vformat(wchar_t **error_str, const char *format, va_list args)
152{
153 char msg[256];
154 vsnprintf(msg, sizeof(msg), format, args);
155
156 register_error_str(error_str, msg);
157}
158
159/* Set the last global error to be reported by hid_error(NULL).
160 * The given error message will be copied (and decoded according to the
161 * currently locale, so do not pass in string constants).
162 * The last stored global error message is freed.
163 * Use register_global_error(NULL) to indicate "no error". */
164static void register_global_error(const char *msg)
165{
166 register_error_str(&last_global_error_str, msg);
167}
168
169/* Similar to register_global_error, but allows passing a format string into this function. */
170static void register_global_error_format(const char *format, ...)
171{
172 va_list args;
173 va_start(args, format);
174 register_error_str_vformat(&last_global_error_str, format, args);
175 va_end(args);
176}
177
178/* Set the last error for a device to be reported by hid_error(dev).
179 * The given error message will be copied (and decoded according to the
180 * currently locale, so do not pass in string constants).
181 * The last stored device error message is freed.
182 * Use register_device_error(dev, NULL) to indicate "no error". */
183static void register_device_error(hid_device *dev, const char *msg)
184{
185 register_error_str(&dev->last_error_str, msg);
186}
187
188/* Similar to register_device_error, but you can pass a format string into this function. */
189static void register_device_error_format(hid_device *dev, const char *format, ...)
190{
191 va_list args;
192 va_start(args, format);
193 register_error_str_vformat(&dev->last_error_str, format, args);
194 va_end(args);
195}
196
197/* Get an attribute value from a udev_device and return it as a whar_t
198 string. The returned string must be freed with free() when done.*/
199static wchar_t *copy_udev_string(struct udev_device *dev, const char *udev_name)
200{
201 return utf8_to_wchar_t(udev_device_get_sysattr_value(dev, udev_name));
202}
203
204/*
205 * Gets the size of the HID item at the given position
206 * Returns 1 if successful, 0 if an invalid key
207 * Sets data_len and key_size when successful
208 */
209static int get_hid_item_size(const __u8 *report_descriptor, __u32 size, unsigned int pos, int *data_len, int *key_size)
210{
211 int key = report_descriptor[pos];
212 int size_code;
213
214 /*
215 * This is a Long Item. The next byte contains the
216 * length of the data section (value) for this key.
217 * See the HID specification, version 1.11, section
218 * 6.2.2.3, titled "Long Items."
219 */
220 if ((key & 0xf0) == 0xf0) {
221 if (pos + 1 < size)
222 {
223 *data_len = report_descriptor[pos + 1];
224 *key_size = 3;
225 return 1;
226 }
227 *data_len = 0; /* malformed report */
228 *key_size = 0;
229 }
230
231 /*
232 * This is a Short Item. The bottom two bits of the
233 * key contain the size code for the data section
234 * (value) for this key. Refer to the HID
235 * specification, version 1.11, section 6.2.2.2,
236 * titled "Short Items."
237 */
238 size_code = key & 0x3;
239 switch (size_code) {
240 case 0:
241 case 1:
242 case 2:
243 *data_len = size_code;
244 *key_size = 1;
245 return 1;
246 case 3:
247 *data_len = 4;
248 *key_size = 1;
249 return 1;
250 default:
251 /* Can't ever happen since size_code is & 0x3 */
252 *data_len = 0;
253 *key_size = 0;
254 break;
255 }
256
257 /* malformed report */
258 return 0;
259}
260
261/*
262 * Get bytes from a HID Report Descriptor.
263 * Only call with a num_bytes of 0, 1, 2, or 4.
264 */
265static __u32 get_hid_report_bytes(const __u8 *rpt, size_t len, size_t num_bytes, size_t cur)
266{
267 /* Return if there aren't enough bytes. */
268 if (cur + num_bytes >= len)
269 return 0;
270
271 if (num_bytes == 0)
272 return 0;
273 else if (num_bytes == 1)
274 return rpt[cur + 1];
275 else if (num_bytes == 2)
276 return (rpt[cur + 2] * 256 + rpt[cur + 1]);
277 else if (num_bytes == 4)
278 return (
279 rpt[cur + 4] * 0x01000000 +
280 rpt[cur + 3] * 0x00010000 +
281 rpt[cur + 2] * 0x00000100 +
282 rpt[cur + 1] * 0x00000001
283 );
284 else
285 return 0;
286}
287
288/*
289 * Iterates until the end of a Collection.
290 * Assumes that *pos is exactly at the beginning of a Collection.
291 * Skips all nested Collection, i.e. iterates until the end of current level Collection.
292 *
293 * The return value is non-0 when an end of current Collection is found,
294 * 0 when error is occurred (broken Descriptor, end of a Collection is found before its begin,
295 * or no Collection is found at all).
296 */
297static int hid_iterate_over_collection(const __u8 *report_descriptor, __u32 size, unsigned int *pos, int *data_len, int *key_size)
298{
299 int collection_level = 0;
300
301 while (*pos < size) {
302 int key = report_descriptor[*pos];
303 int key_cmd = key & 0xfc;
304
305 /* Determine data_len and key_size */
306 if (!get_hid_item_size(report_descriptor, size, *pos, data_len, key_size))
307 return 0; /* malformed report */
308
309 switch (key_cmd) {
310 case 0xa0: /* Collection 6.2.2.4 (Main) */
311 collection_level++;
312 break;
313 case 0xc0: /* End Collection 6.2.2.4 (Main) */
314 collection_level--;
315 break;
316 }
317
318 if (collection_level < 0) {
319 /* Broken descriptor or someone is using this function wrong,
320 * i.e. should be called exactly at the collection start */
321 return 0;
322 }
323
324 if (collection_level == 0) {
325 /* Found it!
326 * Also possible when called not at the collection start, but should not happen if used correctly */
327 return 1;
328 }
329
330 *pos += *data_len + *key_size;
331 }
332
333 return 0; /* Did not find the end of a Collection */
334}
335
336struct hid_usage_iterator {
337 unsigned int pos;
338 int usage_page_found;
339 unsigned short usage_page;
340};
341
342/*
343 * Retrieves the device's Usage Page and Usage from the report descriptor.
344 * The algorithm returns the current Usage Page/Usage pair whenever a new
345 * Collection is found and a Usage Local Item is currently in scope.
346 * Usage Local Items are consumed by each Main Item (See. 6.2.2.8).
347 * The algorithm should give similar results as Apple's:
348 * https://developer.apple.com/documentation/iokit/kiohiddeviceusagepairskey?language=objc
349 * Physical Collections are also matched (macOS does the same).
350 *
351 * This function can be called repeatedly until it returns non-0
352 * Usage is found. pos is the starting point (initially 0) and will be updated
353 * to the next search position.
354 *
355 * The return value is 0 when a pair is found.
356 * 1 when finished processing descriptor.
357 * -1 on a malformed report.
358 */
359static int get_next_hid_usage(const __u8 *report_descriptor, __u32 size, struct hid_usage_iterator *ctx, unsigned short *usage_page, unsigned short *usage)
360{
361 int data_len, key_size;
362 int initial = ctx->pos == 0; /* Used to handle case where no top-level application collection is defined */
363
364 int usage_found = 0;
365
366 while (ctx->pos < size) {
367 int key = report_descriptor[ctx->pos];
368 int key_cmd = key & 0xfc;
369
370 /* Determine data_len and key_size */
371 if (!get_hid_item_size(report_descriptor, size, ctx->pos, &data_len, &key_size))
372 return -1; /* malformed report */
373
374 switch (key_cmd) {
375 case 0x4: /* Usage Page 6.2.2.7 (Global) */
376 ctx->usage_page = get_hid_report_bytes(report_descriptor, size, data_len, ctx->pos);
377 ctx->usage_page_found = 1;
378 break;
379
380 case 0x8: /* Usage 6.2.2.8 (Local) */
381 if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */
382 ctx->usage_page = get_hid_report_bytes(report_descriptor, size, 2, ctx->pos + 2);
383 ctx->usage_page_found = 1;
384 *usage = get_hid_report_bytes(report_descriptor, size, 2, ctx->pos);
385 usage_found = 1;
386 }
387 else {
388 *usage = get_hid_report_bytes(report_descriptor, size, data_len, ctx->pos);
389 usage_found = 1;
390 }
391 break;
392
393 case 0xa0: /* Collection 6.2.2.4 (Main) */
394 if (!hid_iterate_over_collection(report_descriptor, size, &ctx->pos, &data_len, &key_size)) {
395 return -1;
396 }
397
398 /* A pair is valid - to be reported when Collection is found */
399 if (usage_found && ctx->usage_page_found) {
400 *usage_page = ctx->usage_page;
401 return 0;
402 }
403
404 break;
405 }
406
407 /* Skip over this key and its associated data */
408 ctx->pos += data_len + key_size;
409 }
410
411 /* If no top-level application collection is found and usage page/usage pair is found, pair is valid
412 https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections */
413 if (initial && usage_found && ctx->usage_page_found) {
414 *usage_page = ctx->usage_page;
415 return 0; /* success */
416 }
417
418 return 1; /* finished processing */
419}
420
421/*
422 * Retrieves the hidraw report descriptor from a file.
423 * When using this form, <sysfs_path>/device/report_descriptor, elevated privileges are not required.
424 */
425static int get_hid_report_descriptor(const char *rpt_path, struct hidraw_report_descriptor *rpt_desc)
426{
427 int rpt_handle;
428 ssize_t res;
429
430 rpt_handle = open(rpt_path, O_RDONLY | O_CLOEXEC);
431 if (rpt_handle < 0) {
432 register_global_error_format("open failed (%s): %s", rpt_path, strerror(errno));
433 return -1;
434 }
435
436 /*
437 * Read in the Report Descriptor
438 * The sysfs file has a maximum size of 4096 (which is the same as HID_MAX_DESCRIPTOR_SIZE) so we should always
439 * be ok when reading the descriptor.
440 * In practice if the HID descriptor is any larger I suspect many other things will break.
441 */
442 memset(rpt_desc, 0x0, sizeof(*rpt_desc));
443 res = read(rpt_handle, rpt_desc->value, HID_MAX_DESCRIPTOR_SIZE);
444 if (res < 0) {
445 register_global_error_format("read failed (%s): %s", rpt_path, strerror(errno));
446 }
447 rpt_desc->size = (__u32) res;
448
449 close(rpt_handle);
450 return (int) res;
451}
452
453/* return size of the descriptor, or -1 on failure */
454static int get_hid_report_descriptor_from_sysfs(const char *sysfs_path, struct hidraw_report_descriptor *rpt_desc)
455{
456 int res = -1;
457 /* Construct <sysfs_path>/device/report_descriptor */
458 size_t rpt_path_len = strlen(sysfs_path) + 25 + 1;
459 char* rpt_path = (char*) calloc(1, rpt_path_len);
460 snprintf(rpt_path, rpt_path_len, "%s/device/report_descriptor", sysfs_path);
461
462 res = get_hid_report_descriptor(rpt_path, rpt_desc);
463 free(rpt_path);
464
465 return res;
466}
467
468/* return non-zero if successfully parsed */
469static int parse_hid_vid_pid_from_uevent(const char *uevent, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id)
470{
471 char tmp[1024];
472 size_t uevent_len = strlen(uevent);
473 if (uevent_len > sizeof(tmp) - 1)
474 uevent_len = sizeof(tmp) - 1;
475 memcpy(tmp, uevent, uevent_len);
476 tmp[uevent_len] = '\0';
477
478 char *saveptr = NULL;
479 char *line;
480 char *key;
481 char *value;
482
483 line = strtok_r(tmp, "\n", &saveptr);
484 while (line != NULL) {
485 /* line: "KEY=value" */
486 key = line;
487 value = strchr(line, '=');
488 if (!value) {
489 goto next_line;
490 }
491 *value = '\0';
492 value++;
493
494 if (strcmp(key, "HID_ID") == 0) {
495 /**
496 * type vendor product
497 * HID_ID=0003:000005AC:00008242
498 **/
499 int ret = sscanf(value, "%x:%hx:%hx", bus_type, vendor_id, product_id);
500 if (ret == 3) {
501 return 1;
502 }
503 }
504
505next_line:
506 line = strtok_r(NULL, "\n", &saveptr);
507 }
508
509 register_global_error("Couldn't find/parse HID_ID");
510 return 0;
511}
512
513/* return non-zero if successfully parsed */
514static int parse_hid_vid_pid_from_uevent_path(const char *uevent_path, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id)
515{
516 int handle;
517 ssize_t res;
518
519 handle = open(uevent_path, O_RDONLY | O_CLOEXEC);
520 if (handle < 0) {
521 register_global_error_format("open failed (%s): %s", uevent_path, strerror(errno));
522 return 0;
523 }
524
525 char buf[1024];
526 res = read(handle, buf, sizeof(buf) - 1); /* -1 for '\0' at the end */
527 close(handle);
528
529 if (res < 0) {
530 register_global_error_format("read failed (%s): %s", uevent_path, strerror(errno));
531 return 0;
532 }
533
534 buf[res] = '\0';
535 return parse_hid_vid_pid_from_uevent(buf, bus_type, vendor_id, product_id);
536}
537
538/* return non-zero if successfully read/parsed */
539static int parse_hid_vid_pid_from_sysfs(const char *sysfs_path, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id)
540{
541 int res = 0;
542 /* Construct <sysfs_path>/device/uevent */
543 size_t uevent_path_len = strlen(sysfs_path) + 14 + 1;
544 char* uevent_path = (char*) calloc(1, uevent_path_len);
545 snprintf(uevent_path, uevent_path_len, "%s/device/uevent", sysfs_path);
546
547 res = parse_hid_vid_pid_from_uevent_path(uevent_path, bus_type, vendor_id, product_id);
548 free(uevent_path);
549
550 return res;
551}
552
553static int get_hid_report_descriptor_from_hidraw(hid_device *dev, struct hidraw_report_descriptor *rpt_desc)
554{
555 int desc_size = 0;
556
557 /* Get Report Descriptor Size */
558 int res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
559 if (res < 0) {
560 register_device_error_format(dev, "ioctl(GRDESCSIZE): %s", strerror(errno));
561 return res;
562 }
563
564 /* Get Report Descriptor */
565 memset(rpt_desc, 0x0, sizeof(*rpt_desc));
566 rpt_desc->size = desc_size;
567 res = ioctl(dev->device_handle, HIDIOCGRDESC, rpt_desc);
568 if (res < 0) {
569 register_device_error_format(dev, "ioctl(GRDESC): %s", strerror(errno));
570 }
571
572 return res;
573}
574
575/*
576 * The caller is responsible for free()ing the (newly-allocated) character
577 * strings pointed to by serial_number_utf8 and product_name_utf8 after use.
578 */
579static int parse_uevent_info(const char *uevent, unsigned *bus_type,
580 unsigned short *vendor_id, unsigned short *product_id,
581 char **serial_number_utf8, char **product_name_utf8)
582{
583 char tmp[1024];
584
585 if (!uevent) {
586 return 0;
587 }
588
589 size_t uevent_len = strlen(uevent);
590 if (uevent_len > sizeof(tmp) - 1)
591 uevent_len = sizeof(tmp) - 1;
592 memcpy(tmp, uevent, uevent_len);
593 tmp[uevent_len] = '\0';
594
595 char *saveptr = NULL;
596 char *line;
597 char *key;
598 char *value;
599
600 int found_id = 0;
601 int found_serial = 0;
602 int found_name = 0;
603
604 line = strtok_r(tmp, "\n", &saveptr);
605 while (line != NULL) {
606 /* line: "KEY=value" */
607 key = line;
608 value = strchr(line, '=');
609 if (!value) {
610 goto next_line;
611 }
612 *value = '\0';
613 value++;
614
615 if (strcmp(key, "HID_ID") == 0) {
616 /**
617 * type vendor product
618 * HID_ID=0003:000005AC:00008242
619 **/
620 int ret = sscanf(value, "%x:%hx:%hx", bus_type, vendor_id, product_id);
621 if (ret == 3) {
622 found_id = 1;
623 }
624 } else if (strcmp(key, "HID_NAME") == 0) {
625 /* The caller has to free the product name */
626 *product_name_utf8 = strdup(value);
627 found_name = 1;
628 } else if (strcmp(key, "HID_UNIQ") == 0) {
629 /* The caller has to free the serial number */
630 *serial_number_utf8 = strdup(value);
631 found_serial = 1;
632 }
633
634next_line:
635 line = strtok_r(NULL, "\n", &saveptr);
636 }
637
638 return (found_id && found_name && found_serial);
639}
640
641static int is_BLE(hid_device *dev)
642{
643 struct udev *udev;
644 struct udev_device *udev_dev, *hid_dev;
645 struct stat s;
646 int ret;
647
648 /* Create the udev object */
649 udev = udev_new();
650 if (!udev) {
651 printf("Can't create udev\n");
652 return -1;
653 }
654
655 /* Get the dev_t (major/minor numbers) from the file handle. */
656 if (fstat(dev->device_handle, &s) < 0) {
657 udev_unref(udev);
658 return -1;
659 }
660
661 /* Open a udev device from the dev_t. 'c' means character device. */
662 ret = 0;
663 udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
664 if (udev_dev) {
665 hid_dev = udev_device_get_parent_with_subsystem_devtype(
666 udev_dev,
667 "hid",
668 NULL);
669 if (hid_dev) {
670 unsigned short dev_vid = 0;
671 unsigned short dev_pid = 0;
672 unsigned bus_type = 0;
673 char *serial_number_utf8 = NULL;
674 char *product_name_utf8 = NULL;
675
676 parse_uevent_info(
677 udev_device_get_sysattr_value(hid_dev, "uevent"),
678 &bus_type,
679 &dev_vid,
680 &dev_pid,
681 &serial_number_utf8,
682 &product_name_utf8);
683 free(serial_number_utf8);
684 free(product_name_utf8);
685
686 if (bus_type == BUS_BLUETOOTH) {
687 /* Right now the Steam Controller is the only BLE device that we send feature reports to */
688 if (dev_vid == 0x28de /* Valve */) {
689 ret = 1;
690 }
691 }
692
693 /* hid_dev doesn't need to be (and can't be) unref'd.
694 I'm not sure why, but it'll throw double-free() errors. */
695 }
696 udev_device_unref(udev_dev);
697 }
698
699 udev_unref(udev);
700
701 return ret;
702}
703
704
705static struct hid_device_info * create_device_info_for_device(struct udev_device *raw_dev)
706{
707 struct hid_device_info *root = NULL;
708 struct hid_device_info *cur_dev = NULL;
709
710 const char *sysfs_path;
711 const char *dev_path;
712 const char *str;
713 struct udev_device *hid_dev; /* The device's HID udev node. */
714 struct udev_device *usb_dev; /* The device's USB udev node. */
715 struct udev_device *intf_dev; /* The device's interface (in the USB sense). */
716 unsigned short dev_vid;
717 unsigned short dev_pid;
718 char *serial_number_utf8 = NULL;
719 char *product_name_utf8 = NULL;
720 unsigned bus_type;
721 int result;
722 struct hidraw_report_descriptor report_desc;
723
724 sysfs_path = udev_device_get_syspath(raw_dev);
725 dev_path = udev_device_get_devnode(raw_dev);
726
727 hid_dev = udev_device_get_parent_with_subsystem_devtype(
728 raw_dev,
729 "hid",
730 NULL);
731
732 if (!hid_dev) {
733 /* Unable to find parent hid device. */
734 goto end;
735 }
736
737 result = parse_uevent_info(
738 udev_device_get_sysattr_value(hid_dev, "uevent"),
739 &bus_type,
740 &dev_vid,
741 &dev_pid,
742 &serial_number_utf8,
743 &product_name_utf8);
744
745 if (!result) {
746 /* parse_uevent_info() failed for at least one field. */
747 goto end;
748 }
749
750 /* Filter out unhandled devices right away */
751 switch (bus_type) {
752 case BUS_BLUETOOTH:
753 case BUS_I2C:
754 case BUS_USB:
755 case BUS_SPI:
756 break;
757
758 default:
759 goto end;
760 }
761
762 /* Create the record. */
763 root = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
764 if (!root)
765 goto end;
766
767 cur_dev = root;
768
769 /* Fill out the record */
770 cur_dev->next = NULL;
771 cur_dev->path = dev_path? strdup(dev_path): NULL;
772
773 /* VID/PID */
774 cur_dev->vendor_id = dev_vid;
775 cur_dev->product_id = dev_pid;
776
777 /* Serial Number */
778 cur_dev->serial_number = utf8_to_wchar_t(serial_number_utf8);
779
780 /* Release Number */
781 cur_dev->release_number = 0x0;
782
783 /* Interface Number */
784 cur_dev->interface_number = -1;
785
786 switch (bus_type) {
787 case BUS_USB:
788 /* The device pointed to by raw_dev contains information about
789 the hidraw device. In order to get information about the
790 USB device, get the parent device with the
791 subsystem/devtype pair of "usb"/"usb_device". This will
792 be several levels up the tree, but the function will find
793 it. */
794 usb_dev = udev_device_get_parent_with_subsystem_devtype(
795 raw_dev,
796 "usb",
797 "usb_device");
798
799 /* uhid USB devices
800 * Since this is a virtual hid interface, no USB information will
801 * be available. */
802 if (!usb_dev) {
803 /* Manufacturer and Product strings */
804 cur_dev->manufacturer_string = wcsdup(L"");
805 cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
806 break;
807 }
808
809 cur_dev->manufacturer_string = copy_udev_string(usb_dev, "manufacturer");
810 cur_dev->product_string = copy_udev_string(usb_dev, "product");
811
812 cur_dev->bus_type = HID_API_BUS_USB;
813
814 str = udev_device_get_sysattr_value(usb_dev, "bcdDevice");
815 cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;
816
817 /* Get a handle to the interface's udev node. */
818 intf_dev = udev_device_get_parent_with_subsystem_devtype(
819 raw_dev,
820 "usb",
821 "usb_interface");
822 if (intf_dev) {
823 str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
824 cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
825 }
826
827 break;
828
829 case BUS_BLUETOOTH:
830 cur_dev->manufacturer_string = wcsdup(L"");
831 cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
832
833 cur_dev->bus_type = HID_API_BUS_BLUETOOTH;
834
835 break;
836 case BUS_I2C:
837 cur_dev->manufacturer_string = wcsdup(L"");
838 cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
839
840 cur_dev->bus_type = HID_API_BUS_I2C;
841
842 break;
843
844 case BUS_SPI:
845 cur_dev->manufacturer_string = wcsdup(L"");
846 cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
847
848 cur_dev->bus_type = HID_API_BUS_SPI;
849
850 break;
851
852 default:
853 /* Unknown device type - this should never happen, as we
854 * check for USB and Bluetooth devices above */
855 break;
856 }
857
858 /* Usage Page and Usage */
859 result = get_hid_report_descriptor_from_sysfs(sysfs_path, &report_desc);
860 if (result >= 0) {
861 unsigned short page = 0, usage = 0;
862 struct hid_usage_iterator usage_iterator;
863 memset(&usage_iterator, 0, sizeof(usage_iterator));
864
865 /*
866 * Parse the first usage and usage page
867 * out of the report descriptor.
868 */
869 if (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage)) {
870 cur_dev->usage_page = page;
871 cur_dev->usage = usage;
872 }
873
874 /*
875 * Parse any additional usage and usage pages
876 * out of the report descriptor.
877 */
878 while (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage)) {
879 /* Create new record for additional usage pairs */
880 struct hid_device_info *tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
881 struct hid_device_info *prev_dev = cur_dev;
882
883 if (!tmp)
884 continue;
885 cur_dev->next = tmp;
886 cur_dev = tmp;
887
888 /* Update fields */
889 cur_dev->path = dev_path? strdup(dev_path): NULL;
890 cur_dev->vendor_id = dev_vid;
891 cur_dev->product_id = dev_pid;
892 cur_dev->serial_number = prev_dev->serial_number? wcsdup(prev_dev->serial_number): NULL;
893 cur_dev->release_number = prev_dev->release_number;
894 cur_dev->interface_number = prev_dev->interface_number;
895 cur_dev->manufacturer_string = prev_dev->manufacturer_string? wcsdup(prev_dev->manufacturer_string): NULL;
896 cur_dev->product_string = prev_dev->product_string? wcsdup(prev_dev->product_string): NULL;
897 cur_dev->usage_page = page;
898 cur_dev->usage = usage;
899 cur_dev->bus_type = prev_dev->bus_type;
900 }
901 }
902
903#ifdef HIDAPI_IGNORE_DEVICE
904 {
905 struct hid_device_info *prev_dev = NULL;
906
907 cur_dev = root;
908 while (cur_dev) {
909 if (HIDAPI_IGNORE_DEVICE(cur_dev->bus_type, cur_dev->vendor_id, cur_dev->product_id, cur_dev->usage_page, cur_dev->usage)) {
910 struct hid_device_info *tmp = cur_dev;
911
912 cur_dev = tmp->next;
913 if (prev_dev) {
914 prev_dev->next = cur_dev;
915 } else {
916 root = cur_dev;
917 }
918 tmp->next = NULL;
919
920 hid_free_enumeration(tmp);
921 } else {
922 prev_dev = cur_dev;
923 cur_dev = cur_dev->next;
924 }
925 }
926 }
927#endif
928
929end:
930 free(serial_number_utf8);
931 free(product_name_utf8);
932
933 return root;
934}
935
936static struct hid_device_info * create_device_info_for_hid_device(hid_device *dev) {
937 struct udev *udev;
938 struct udev_device *udev_dev;
939 struct stat s;
940 int ret = -1;
941 struct hid_device_info *root = NULL;
942
943 register_device_error(dev, NULL);
944
945 /* Get the dev_t (major/minor numbers) from the file handle. */
946 ret = fstat(dev->device_handle, &s);
947 if (-1 == ret) {
948 register_device_error(dev, "Failed to stat device handle");
949 return NULL;
950 }
951
952 /* Create the udev object */
953 udev = udev_new();
954 if (!udev) {
955 register_device_error(dev, "Couldn't create udev context");
956 return NULL;
957 }
958
959 /* Open a udev device from the dev_t. 'c' means character device. */
960 udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
961 if (udev_dev) {
962 root = create_device_info_for_device(udev_dev);
963 }
964
965 if (!root) {
966 /* TODO: have a better error reporting via create_device_info_for_device */
967 register_device_error(dev, "Couldn't create hid_device_info");
968 }
969
970 udev_device_unref(udev_dev);
971 udev_unref(udev);
972
973 return root;
974}
975
976HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void)
977{
978 return &api_version;
979}
980
981HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
982{
983 return HID_API_VERSION_STR;
984}
985
986int HID_API_EXPORT hid_init(void)
987{
988 const char *locale;
989
990 /* indicate no error */
991 register_global_error(NULL);
992
993 /* Set the locale if it's not set. */
994 locale = setlocale(LC_CTYPE, NULL);
995 if (!locale)
996 setlocale(LC_CTYPE, "");
997
998 return 0;
999}
1000
1001int HID_API_EXPORT hid_exit(void)
1002{
1003 /* Free global error message */
1004 register_global_error(NULL);
1005
1006 return 0;
1007}
1008
1009struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
1010{
1011 struct udev *udev;
1012 struct udev_enumerate *enumerate;
1013 struct udev_list_entry *devices, *dev_list_entry;
1014
1015 struct hid_device_info *root = NULL; /* return object */
1016 struct hid_device_info *cur_dev = NULL;
1017
1018 hid_init();
1019 /* register_global_error: global error is reset by hid_init */
1020
1021 /* Create the udev object */
1022 udev = udev_new();
1023 if (!udev) {
1024 register_global_error("Couldn't create udev context");
1025 return NULL;
1026 }
1027
1028 /* Create a list of the devices in the 'hidraw' subsystem. */
1029 enumerate = udev_enumerate_new(udev);
1030 udev_enumerate_add_match_subsystem(enumerate, "hidraw");
1031 udev_enumerate_scan_devices(enumerate);
1032 devices = udev_enumerate_get_list_entry(enumerate);
1033 /* For each item, see if it matches the vid/pid, and if so
1034 create a udev_device record for it */
1035 udev_list_entry_foreach(dev_list_entry, devices) {
1036 const char *sysfs_path;
1037 unsigned short dev_vid = 0;
1038 unsigned short dev_pid = 0;
1039 unsigned bus_type = 0;
1040 struct udev_device *raw_dev; /* The device's hidraw udev node. */
1041 struct hid_device_info * tmp;
1042
1043 /* Get the filename of the /sys entry for the device
1044 and create a udev_device object (dev) representing it */
1045 sysfs_path = udev_list_entry_get_name(dev_list_entry);
1046 if (!sysfs_path)
1047 continue;
1048
1049 if (vendor_id != 0 || product_id != 0) {
1050 if (!parse_hid_vid_pid_from_sysfs(sysfs_path, &bus_type, &dev_vid, &dev_pid))
1051 continue;
1052
1053 if (vendor_id != 0 && vendor_id != dev_vid)
1054 continue;
1055 if (product_id != 0 && product_id != dev_pid)
1056 continue;
1057 }
1058
1059 raw_dev = udev_device_new_from_syspath(udev, sysfs_path);
1060 if (!raw_dev)
1061 continue;
1062
1063 tmp = create_device_info_for_device(raw_dev);
1064 if (tmp) {
1065 if (cur_dev) {
1066 cur_dev->next = tmp;
1067 }
1068 else {
1069 root = tmp;
1070 }
1071 cur_dev = tmp;
1072
1073 /* move the pointer to the tail of returned list */
1074 while (cur_dev->next != NULL) {
1075 cur_dev = cur_dev->next;
1076 }
1077 }
1078
1079 udev_device_unref(raw_dev);
1080 }
1081 /* Free the enumerator and udev objects. */
1082 udev_enumerate_unref(enumerate);
1083 udev_unref(udev);
1084
1085 if (root == NULL) {
1086 if (vendor_id == 0 && product_id == 0) {
1087 register_global_error("No HID devices found in the system.");
1088 } else {
1089 register_global_error("No HID devices with requested VID/PID found in the system.");
1090 }
1091 }
1092
1093 return root;
1094}
1095
1096void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
1097{
1098 struct hid_device_info *d = devs;
1099 while (d) {
1100 struct hid_device_info *next = d->next;
1101 free(d->path);
1102 free(d->serial_number);
1103 free(d->manufacturer_string);
1104 free(d->product_string);
1105 free(d);
1106 d = next;
1107 }
1108}
1109
1110hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
1111{
1112 struct hid_device_info *devs, *cur_dev;
1113 const char *path_to_open = NULL;
1114 hid_device *handle = NULL;
1115
1116 /* register_global_error: global error is reset by hid_enumerate/hid_init */
1117 devs = hid_enumerate(vendor_id, product_id);
1118 if (devs == NULL) {
1119 /* register_global_error: global error is already set by hid_enumerate */
1120 return NULL;
1121 }
1122
1123 cur_dev = devs;
1124 while (cur_dev) {
1125 if (cur_dev->vendor_id == vendor_id &&
1126 cur_dev->product_id == product_id) {
1127 if (serial_number) {
1128 if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
1129 path_to_open = cur_dev->path;
1130 break;
1131 }
1132 }
1133 else {
1134 path_to_open = cur_dev->path;
1135 break;
1136 }
1137 }
1138 cur_dev = cur_dev->next;
1139 }
1140
1141 if (path_to_open) {
1142 /* Open the device */
1143 handle = hid_open_path(path_to_open);
1144 } else {
1145 register_global_error("Device with requested VID/PID/(SerialNumber) not found");
1146 }
1147
1148 hid_free_enumeration(devs);
1149
1150 return handle;
1151}
1152
1153hid_device * HID_API_EXPORT hid_open_path(const char *path)
1154{
1155 hid_device *dev = NULL;
1156
1157 hid_init();
1158 /* register_global_error: global error is reset by hid_init */
1159
1160 dev = new_hid_device();
1161 if (!dev) {
1162 register_global_error("Couldn't allocate memory");
1163 return NULL;
1164 }
1165
1166 const int MAX_ATTEMPTS = 50;
1167 int attempt;
1168 for (attempt = 1; attempt <= MAX_ATTEMPTS; ++attempt) {
1169 dev->device_handle = open(path, O_RDWR | O_CLOEXEC);
1170 if (dev->device_handle < 0 && errno == EACCES) {
1171 /* udev might be setting up permissions, wait a bit and try again */
1172 usleep(1 * 1000);
1173 continue;
1174 }
1175 break;
1176 }
1177
1178 if (dev->device_handle >= 0) {
1179 int res, desc_size = 0;
1180
1181 /* Make sure this is a HIDRAW device - responds to HIDIOCGRDESCSIZE */
1182 res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
1183 if (res < 0) {
1184 hid_close(dev);
1185 register_global_error_format("ioctl(GRDESCSIZE) error for '%s', not a HIDRAW device?: %s", path, strerror(errno));
1186 return NULL;
1187 }
1188
1189 dev->needs_ble_hack = (is_BLE(dev) == 1);
1190
1191 return dev;
1192 }
1193 else {
1194 /* Unable to open a device. */
1195 free(dev);
1196 register_global_error_format("Failed to open a device with path '%s': %s", path, strerror(errno));
1197 return NULL;
1198 }
1199}
1200
1201
1202int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
1203{
1204 int bytes_written;
1205
1206 if (!data || (length == 0)) {
1207 errno = EINVAL;
1208 register_device_error(dev, strerror(errno));
1209 return -1;
1210 }
1211
1212 bytes_written = write(dev->device_handle, data, length);
1213
1214 register_device_error(dev, (bytes_written == -1)? strerror(errno): NULL);
1215
1216 return bytes_written;
1217}
1218
1219
1220int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1221{
1222 /* Set device error to none */
1223 register_device_error(dev, NULL);
1224
1225 int bytes_read;
1226
1227 if (milliseconds >= 0) {
1228 /* Milliseconds is either 0 (non-blocking) or > 0 (contains
1229 a valid timeout). In both cases we want to call poll()
1230 and wait for data to arrive. Don't rely on non-blocking
1231 operation (O_NONBLOCK) since some kernels don't seem to
1232 properly report device disconnection through read() when
1233 in non-blocking mode. */
1234 int ret;
1235 struct pollfd fds;
1236
1237 fds.fd = dev->device_handle;
1238 fds.events = POLLIN;
1239 fds.revents = 0;
1240 ret = poll(&fds, 1, milliseconds);
1241 if (ret == 0) {
1242 /* Timeout */
1243 return ret;
1244 }
1245 if (ret == -1) {
1246 /* Error */
1247 register_device_error(dev, strerror(errno));
1248 return ret;
1249 }
1250 else {
1251 /* Check for errors on the file descriptor. This will
1252 indicate a device disconnection. */
1253 if (fds.revents & (POLLERR | POLLHUP | POLLNVAL)) {
1254 // We cannot use strerror() here as no -1 was returned from poll().
1255 register_device_error(dev, "hid_read_timeout: unexpected poll error (device disconnected)");
1256 return -1;
1257 }
1258 }
1259 }
1260
1261 bytes_read = read(dev->device_handle, data, length);
1262 if (bytes_read < 0) {
1263 if (errno == EAGAIN || errno == EINPROGRESS)
1264 bytes_read = 0;
1265 else
1266 register_device_error(dev, strerror(errno));
1267 }
1268
1269 return bytes_read;
1270}
1271
1272int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
1273{
1274 return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
1275}
1276
1277int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
1278{
1279 /* Do all non-blocking in userspace using poll(), since it looks
1280 like there's a bug in the kernel in some versions where
1281 read() will not return -1 on disconnection of the USB device */
1282
1283 dev->blocking = !nonblock;
1284 return 0; /* Success */
1285}
1286
1287
1288int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
1289{
1290 static const int MAX_RETRIES = 50;
1291 int retry;
1292 int res;
1293
1294 register_device_error(dev, NULL);
1295
1296 for (retry = 0; retry < MAX_RETRIES; ++retry) {
1297 res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data);
1298 if (res < 0 && errno == EPIPE) {
1299 /* Try again... */
1300 continue;
1301 }
1302
1303 if (res < 0)
1304 register_device_error_format(dev, "ioctl (SFEATURE): %s", strerror(errno));
1305 break;
1306 }
1307 return res;
1308}
1309
1310int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
1311{
1312 int res;
1313 unsigned char report = data[0];
1314
1315 register_device_error(dev, NULL);
1316
1317 res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
1318 if (res < 0)
1319 register_device_error_format(dev, "ioctl (GFEATURE): %s", strerror(errno));
1320 else if (dev->needs_ble_hack) {
1321 /* Versions of BlueZ before 5.56 don't include the report in the data,
1322 * and versions of BlueZ >= 5.56 include 2 copies of the report.
1323 * We'll fix it so that there is a single copy of the report in both cases
1324 */
1325 if (data[0] == report && data[1] == report) {
1326 memmove(&data[0], &data[1], res);
1327 } else if (data[0] != report) {
1328 memmove(&data[1], &data[0], res);
1329 data[0] = report;
1330 ++res;
1331 }
1332 }
1333
1334 return res;
1335}
1336
1337int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
1338{
1339 int res;
1340
1341 register_device_error(dev, NULL);
1342
1343 res = ioctl(dev->device_handle, HIDIOCGINPUT(length), data);
1344 if (res < 0)
1345 register_device_error_format(dev, "ioctl (GINPUT): %s", strerror(errno));
1346
1347 return res;
1348}
1349
1350void HID_API_EXPORT hid_close(hid_device *dev)
1351{
1352 if (!dev)
1353 return;
1354
1355 close(dev->device_handle);
1356
1357 /* Free the device error message */
1358 register_device_error(dev, NULL);
1359
1360 hid_free_enumeration(dev->device_info);
1361
1362 free(dev);
1363}
1364
1365
1366int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
1367{
1368 if (!string || !maxlen) {
1369 register_device_error(dev, "Zero buffer/length");
1370 return -1;
1371 }
1372
1373 struct hid_device_info *info = hid_get_device_info(dev);
1374 if (!info) {
1375 // hid_get_device_info will have set an error already
1376 return -1;
1377 }
1378
1379 if (info->manufacturer_string) {
1380 wcsncpy(string, info->manufacturer_string, maxlen);
1381 string[maxlen - 1] = L'\0';
1382 }
1383 else {
1384 string[0] = L'\0';
1385 }
1386
1387 return 0;
1388}
1389
1390int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
1391{
1392 if (!string || !maxlen) {
1393 register_device_error(dev, "Zero buffer/length");
1394 return -1;
1395 }
1396
1397 struct hid_device_info *info = hid_get_device_info(dev);
1398 if (!info) {
1399 // hid_get_device_info will have set an error already
1400 return -1;
1401 }
1402
1403 if (info->product_string) {
1404 wcsncpy(string, info->product_string, maxlen);
1405 string[maxlen - 1] = L'\0';
1406 }
1407 else {
1408 string[0] = L'\0';
1409 }
1410
1411 return 0;
1412}
1413
1414int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1415{
1416 if (!string || !maxlen) {
1417 register_device_error(dev, "Zero buffer/length");
1418 return -1;
1419 }
1420
1421 struct hid_device_info *info = hid_get_device_info(dev);
1422 if (!info) {
1423 // hid_get_device_info will have set an error already
1424 return -1;
1425 }
1426
1427 if (info->serial_number) {
1428 wcsncpy(string, info->serial_number, maxlen);
1429 string[maxlen - 1] = L'\0';
1430 }
1431 else {
1432 string[0] = L'\0';
1433 }
1434
1435 return 0;
1436}
1437
1438
1439HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_device *dev) {
1440 if (!dev->device_info) {
1441 // Lazy initialize device_info
1442 dev->device_info = create_device_info_for_hid_device(dev);
1443 }
1444
1445 // create_device_info_for_hid_device will set an error if needed
1446 return dev->device_info;
1447}
1448
1449int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1450{
1451 (void)string_index;
1452 (void)string;
1453 (void)maxlen;
1454
1455 register_device_error(dev, "hid_get_indexed_string: not supported by hidraw");
1456
1457 return -1;
1458}
1459
1460
1461int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
1462{
1463 struct hidraw_report_descriptor rpt_desc;
1464 int res = get_hid_report_descriptor_from_hidraw(dev, &rpt_desc);
1465 if (res < 0) {
1466 /* error already registered */
1467 return res;
1468 }
1469
1470 if (rpt_desc.size < buf_size) {
1471 buf_size = (size_t) rpt_desc.size;
1472 }
1473
1474 memcpy(buf, rpt_desc.value, buf_size);
1475
1476 return (int) buf_size;
1477}
1478
1479
1480/* Passing in NULL means asking for the last global error message. */
1481HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
1482{
1483 if (dev) {
1484 if (dev->last_error_str == NULL)
1485 return L"Success";
1486 return dev->last_error_str;
1487 }
1488
1489 if (last_global_error_str == NULL)
1490 return L"Success";
1491 return last_global_error_str;
1492}
diff --git a/contrib/SDL-3.2.8/src/hidapi/m4/ax_pthread.m4 b/contrib/SDL-3.2.8/src/hidapi/m4/ax_pthread.m4
new file mode 100644
index 0000000..d90de34
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/m4/ax_pthread.m4
@@ -0,0 +1,309 @@
1# ===========================================================================
2# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
3# ===========================================================================
4#
5# SYNOPSIS
6#
7# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
8#
9# DESCRIPTION
10#
11# This macro figures out how to build C programs using POSIX threads. It
12# sets the PTHREAD_LIBS output variable to the threads library and linker
13# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
14# flags that are needed. (The user can also force certain compiler
15# flags/libs to be tested by setting these environment variables.)
16#
17# Also sets PTHREAD_CC to any special C compiler that is needed for
18# multi-threaded programs (defaults to the value of CC otherwise). (This
19# is necessary on AIX to use the special cc_r compiler alias.)
20#
21# NOTE: You are assumed to not only compile your program with these flags,
22# but also link it with them as well. e.g. you should link with
23# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
24#
25# If you are only building threads programs, you may wish to use these
26# variables in your default LIBS, CFLAGS, and CC:
27#
28# LIBS="$PTHREAD_LIBS $LIBS"
29# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
30# CC="$PTHREAD_CC"
31#
32# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
33# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
34# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
35#
36# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
37# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
38# PTHREAD_CFLAGS.
39#
40# ACTION-IF-FOUND is a list of shell commands to run if a threads library
41# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
42# is not found. If ACTION-IF-FOUND is not specified, the default action
43# will define HAVE_PTHREAD.
44#
45# Please let the authors know if this macro fails on any platform, or if
46# you have any other suggestions or comments. This macro was based on work
47# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
48# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
49# Alejandro Forero Cuervo to the autoconf macro repository. We are also
50# grateful for the helpful feedback of numerous users.
51#
52# Updated for Autoconf 2.68 by Daniel Richard G.
53#
54# LICENSE
55#
56# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
57# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
58#
59# This program is free software: you can redistribute it and/or modify it
60# under the terms of the GNU General Public License as published by the
61# Free Software Foundation, either version 3 of the License, or (at your
62# option) any later version.
63#
64# This program is distributed in the hope that it will be useful, but
65# WITHOUT ANY WARRANTY; without even the implied warranty of
66# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
67# Public License for more details.
68#
69# You should have received a copy of the GNU General Public License along
70# with this program. If not, see <http://www.gnu.org/licenses/>.
71#
72# As a special exception, the respective Autoconf Macro's copyright owner
73# gives unlimited permission to copy, distribute and modify the configure
74# scripts that are the output of Autoconf when processing the Macro. You
75# need not follow the terms of the GNU General Public License when using
76# or distributing such scripts, even though portions of the text of the
77# Macro appear in them. The GNU General Public License (GPL) does govern
78# all other use of the material that constitutes the Autoconf Macro.
79#
80# This special exception to the GPL applies to versions of the Autoconf
81# Macro released by the Autoconf Archive. When you make and distribute a
82# modified version of the Autoconf Macro, you may extend this special
83# exception to the GPL to apply to your modified version as well.
84
85#serial 18
86
87AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
88AC_DEFUN([AX_PTHREAD], [
89AC_REQUIRE([AC_CANONICAL_HOST])
90AC_LANG_PUSH([C])
91ax_pthread_ok=no
92
93# We used to check for pthread.h first, but this fails if pthread.h
94# requires special compiler flags (e.g. on True64 or Sequent).
95# It gets checked for in the link test anyway.
96
97# First of all, check if the user has set any of the PTHREAD_LIBS,
98# etcetera environment variables, and if threads linking works using
99# them:
100if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
101 save_CFLAGS="$CFLAGS"
102 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
103 save_LIBS="$LIBS"
104 LIBS="$PTHREAD_LIBS $LIBS"
105 AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
106 AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
107 AC_MSG_RESULT($ax_pthread_ok)
108 if test x"$ax_pthread_ok" = xno; then
109 PTHREAD_LIBS=""
110 PTHREAD_CFLAGS=""
111 fi
112 LIBS="$save_LIBS"
113 CFLAGS="$save_CFLAGS"
114fi
115
116# We must check for the threads library under a number of different
117# names; the ordering is very important because some systems
118# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
119# libraries is broken (non-POSIX).
120
121# Create a list of thread flags to try. Items starting with a "-" are
122# C compiler flags, and other items are library names, except for "none"
123# which indicates that we try without any flags at all, and "pthread-config"
124# which is a program returning the flags for the Pth emulation library.
125
126ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
127
128# The ordering *is* (sometimes) important. Some notes on the
129# individual items follow:
130
131# pthreads: AIX (must check this before -lpthread)
132# none: in case threads are in libc; should be tried before -Kthread and
133# other compiler flags to prevent continual compiler warnings
134# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
135# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
136# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
137# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
138# -pthreads: Solaris/gcc
139# -mthreads: Mingw32/gcc, Lynx/gcc
140# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
141# doesn't hurt to check since this sometimes defines pthreads too;
142# also defines -D_REENTRANT)
143# ... -mt is also the pthreads flag for HP/aCC
144# pthread: Linux, etcetera
145# --thread-safe: KAI C++
146# pthread-config: use pthread-config program (for GNU Pth library)
147
148case ${host_os} in
149 solaris*)
150
151 # On Solaris (at least, for some versions), libc contains stubbed
152 # (non-functional) versions of the pthreads routines, so link-based
153 # tests will erroneously succeed. (We need to link with -pthreads/-mt/
154 # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
155 # a function called by this macro, so we could check for that, but
156 # who knows whether they'll stub that too in a future libc.) So,
157 # we'll just look for -pthreads and -lpthread first:
158
159 ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
160 ;;
161
162 darwin*)
163 ax_pthread_flags="-pthread $ax_pthread_flags"
164 ;;
165esac
166
167if test x"$ax_pthread_ok" = xno; then
168for flag in $ax_pthread_flags; do
169
170 case $flag in
171 none)
172 AC_MSG_CHECKING([whether pthreads work without any flags])
173 ;;
174
175 -*)
176 AC_MSG_CHECKING([whether pthreads work with $flag])
177 PTHREAD_CFLAGS="$flag"
178 ;;
179
180 pthread-config)
181 AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
182 if test x"$ax_pthread_config" = xno; then continue; fi
183 PTHREAD_CFLAGS="`pthread-config --cflags`"
184 PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
185 ;;
186
187 *)
188 AC_MSG_CHECKING([for the pthreads library -l$flag])
189 PTHREAD_LIBS="-l$flag"
190 ;;
191 esac
192
193 save_LIBS="$LIBS"
194 save_CFLAGS="$CFLAGS"
195 LIBS="$PTHREAD_LIBS $LIBS"
196 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
197
198 # Check for various functions. We must include pthread.h,
199 # since some functions may be macros. (On the Sequent, we
200 # need a special flag -Kthread to make this header compile.)
201 # We check for pthread_join because it is in -lpthread on IRIX
202 # while pthread_create is in libc. We check for pthread_attr_init
203 # due to DEC craziness with -lpthreads. We check for
204 # pthread_cleanup_push because it is one of the few pthread
205 # functions on Solaris that doesn't have a non-functional libc stub.
206 # We try pthread_create on general principles.
207 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
208 static void routine(void *a) { a = 0; }
209 static void *start_routine(void *a) { return a; }],
210 [pthread_t th; pthread_attr_t attr;
211 pthread_create(&th, 0, start_routine, 0);
212 pthread_join(th, 0);
213 pthread_attr_init(&attr);
214 pthread_cleanup_push(routine, 0);
215 pthread_cleanup_pop(0) /* ; */])],
216 [ax_pthread_ok=yes],
217 [])
218
219 LIBS="$save_LIBS"
220 CFLAGS="$save_CFLAGS"
221
222 AC_MSG_RESULT($ax_pthread_ok)
223 if test "x$ax_pthread_ok" = xyes; then
224 break;
225 fi
226
227 PTHREAD_LIBS=""
228 PTHREAD_CFLAGS=""
229done
230fi
231
232# Various other checks:
233if test "x$ax_pthread_ok" = xyes; then
234 save_LIBS="$LIBS"
235 LIBS="$PTHREAD_LIBS $LIBS"
236 save_CFLAGS="$CFLAGS"
237 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
238
239 # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
240 AC_MSG_CHECKING([for joinable pthread attribute])
241 attr_name=unknown
242 for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
243 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
244 [int attr = $attr; return attr /* ; */])],
245 [attr_name=$attr; break],
246 [])
247 done
248 AC_MSG_RESULT($attr_name)
249 if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
250 AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
251 [Define to necessary symbol if this constant
252 uses a non-standard name on your system.])
253 fi
254
255 AC_MSG_CHECKING([if more special flags are required for pthreads])
256 flag=no
257 case ${host_os} in
258 aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
259 osf* | hpux*) flag="-D_REENTRANT";;
260 solaris*)
261 if test "$GCC" = "yes"; then
262 flag="-D_REENTRANT"
263 else
264 flag="-mt -D_REENTRANT"
265 fi
266 ;;
267 esac
268 AC_MSG_RESULT(${flag})
269 if test "x$flag" != xno; then
270 PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
271 fi
272
273 AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
274 ax_cv_PTHREAD_PRIO_INHERIT, [
275 AC_LINK_IFELSE([
276 AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
277 [ax_cv_PTHREAD_PRIO_INHERIT=yes],
278 [ax_cv_PTHREAD_PRIO_INHERIT=no])
279 ])
280 AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
281 AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
282
283 LIBS="$save_LIBS"
284 CFLAGS="$save_CFLAGS"
285
286 # More AIX lossage: must compile with xlc_r or cc_r
287 if test x"$GCC" != xyes; then
288 AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
289 else
290 PTHREAD_CC=$CC
291 fi
292else
293 PTHREAD_CC="$CC"
294fi
295
296AC_SUBST(PTHREAD_LIBS)
297AC_SUBST(PTHREAD_CFLAGS)
298AC_SUBST(PTHREAD_CC)
299
300# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
301if test x"$ax_pthread_ok" = xyes; then
302 ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
303 :
304else
305 ax_pthread_ok=no
306 $2
307fi
308AC_LANG_POP
309])dnl AX_PTHREAD
diff --git a/contrib/SDL-3.2.8/src/hidapi/m4/pkg.m4 b/contrib/SDL-3.2.8/src/hidapi/m4/pkg.m4
new file mode 100644
index 0000000..0048a3f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/m4/pkg.m4
@@ -0,0 +1,157 @@
1# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
2#
3# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18#
19# As a special exception to the GNU General Public License, if you
20# distribute this file as part of a program that contains a
21# configuration script generated by Autoconf, you may include it under
22# the same distribution terms that you use for the rest of that program.
23
24# PKG_PROG_PKG_CONFIG([MIN-VERSION])
25# ----------------------------------
26AC_DEFUN([PKG_PROG_PKG_CONFIG],
27[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
28m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
29AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
30if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
31 AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
32fi
33if test -n "$PKG_CONFIG"; then
34 _pkg_min_version=m4_default([$1], [0.9.0])
35 AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
36 if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
37 AC_MSG_RESULT([yes])
38 else
39 AC_MSG_RESULT([no])
40 PKG_CONFIG=""
41 fi
42
43fi[]dnl
44])# PKG_PROG_PKG_CONFIG
45
46# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
47#
48# Check to see whether a particular set of modules exists. Similar
49# to PKG_CHECK_MODULES(), but does not set variables or print errors.
50#
51#
52# Similar to PKG_CHECK_MODULES, make sure that the first instance of
53# this or PKG_CHECK_MODULES is called, or make sure to call
54# PKG_CHECK_EXISTS manually
55# --------------------------------------------------------------
56AC_DEFUN([PKG_CHECK_EXISTS],
57[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
58if test -n "$PKG_CONFIG" && \
59 AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
60 m4_ifval([$2], [$2], [:])
61m4_ifvaln([$3], [else
62 $3])dnl
63fi])
64
65
66# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
67# ---------------------------------------------
68m4_define([_PKG_CONFIG],
69[if test -n "$PKG_CONFIG"; then
70 if test -n "$$1"; then
71 pkg_cv_[]$1="$$1"
72 else
73 PKG_CHECK_EXISTS([$3],
74 [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
75 [pkg_failed=yes])
76 fi
77else
78 pkg_failed=untried
79fi[]dnl
80])# _PKG_CONFIG
81
82# _PKG_SHORT_ERRORS_SUPPORTED
83# -----------------------------
84AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
85[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
86if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
87 _pkg_short_errors_supported=yes
88else
89 _pkg_short_errors_supported=no
90fi[]dnl
91])# _PKG_SHORT_ERRORS_SUPPORTED
92
93
94# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
95# [ACTION-IF-NOT-FOUND])
96#
97#
98# Note that if there is a possibility the first call to
99# PKG_CHECK_MODULES might not happen, you should be sure to include an
100# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
101#
102#
103# --------------------------------------------------------------
104AC_DEFUN([PKG_CHECK_MODULES],
105[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
106AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
107AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
108
109pkg_failed=no
110AC_MSG_CHECKING([for $1])
111
112_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
113_PKG_CONFIG([$1][_LIBS], [libs], [$2])
114
115m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
116and $1[]_LIBS to avoid the need to call pkg-config.
117See the pkg-config man page for more details.])
118
119if test $pkg_failed = yes; then
120 _PKG_SHORT_ERRORS_SUPPORTED
121 if test $_pkg_short_errors_supported = yes; then
122 $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
123 else
124 $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
125 fi
126 # Put the nasty error message in config.log where it belongs
127 echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
128
129 ifelse([$4], , [AC_MSG_ERROR(dnl
130[Package requirements ($2) were not met:
131
132$$1_PKG_ERRORS
133
134Consider adjusting the PKG_CONFIG_PATH environment variable if you
135installed software in a non-standard prefix.
136
137_PKG_TEXT
138])],
139 [AC_MSG_RESULT([no])
140 $4])
141elif test $pkg_failed = untried; then
142 ifelse([$4], , [AC_MSG_FAILURE(dnl
143[The pkg-config script could not be found or is too old. Make sure it
144is in your PATH or set the PKG_CONFIG environment variable to the full
145path to pkg-config.
146
147_PKG_TEXT
148
149To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
150 [$4])
151else
152 $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
153 $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
154 AC_MSG_RESULT([yes])
155 ifelse([$3], , :, [$3])
156fi[]dnl
157])# PKG_CHECK_MODULES
diff --git a/contrib/SDL-3.2.8/src/hidapi/mac/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/mac/CMakeLists.txt
new file mode 100644
index 0000000..0a1c1d9
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/mac/CMakeLists.txt
@@ -0,0 +1,48 @@
1cmake_minimum_required(VERSION 3.4.3...3.25 FATAL_ERROR)
2
3list(APPEND HIDAPI_PUBLIC_HEADERS "hidapi_darwin.h")
4
5add_library(hidapi_darwin
6 ${HIDAPI_PUBLIC_HEADERS}
7 hid.c
8)
9
10find_package(Threads REQUIRED)
11
12target_link_libraries(hidapi_darwin
13 PUBLIC hidapi_include
14 PRIVATE Threads::Threads
15 PRIVATE "-framework IOKit" "-framework CoreFoundation"
16)
17
18set_target_properties(hidapi_darwin
19 PROPERTIES
20 EXPORT_NAME "darwin"
21 OUTPUT_NAME "hidapi"
22 VERSION ${PROJECT_VERSION}
23 SOVERSION ${PROJECT_VERSION_MAJOR}
24 MACHO_COMPATIBILITY_VERSION ${PROJECT_VERSION_MAJOR}
25 FRAMEWORK_VERSION ${PROJECT_VERSION_MAJOR}
26 PUBLIC_HEADER "${HIDAPI_PUBLIC_HEADERS}"
27)
28
29# compatibility with find_package()
30add_library(hidapi::darwin ALIAS hidapi_darwin)
31# compatibility with raw library link
32add_library(hidapi ALIAS hidapi_darwin)
33
34set(PUBLIC_HEADER_DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
35if(NOT CMAKE_FRAMEWORK)
36 set(PUBLIC_HEADER_DESTINATION "${PUBLIC_HEADER_DESTINATION}/hidapi")
37endif()
38
39if(HIDAPI_INSTALL_TARGETS)
40 install(TARGETS hidapi_darwin EXPORT hidapi
41 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
42 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
43 FRAMEWORK DESTINATION "${CMAKE_INSTALL_LIBDIR}"
44 PUBLIC_HEADER DESTINATION "${PUBLIC_HEADER_DESTINATION}"
45 )
46endif()
47
48hidapi_configure_pc("${PROJECT_ROOT}/pc/hidapi.pc.in")
diff --git a/contrib/SDL-3.2.8/src/hidapi/mac/Makefile-manual b/contrib/SDL-3.2.8/src/hidapi/mac/Makefile-manual
new file mode 100644
index 0000000..667c863
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/mac/Makefile-manual
@@ -0,0 +1,27 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-07-03
7###########################################
8
9all: hidtest
10
11CC=gcc
12COBJS=hid.o ../hidtest/test.o
13OBJS=$(COBJS)
14CFLAGS+=-I../hidapi -I. -Wall -g -c
15LIBS=-framework IOKit -framework CoreFoundation
16
17
18hidtest: $(OBJS)
19 $(CC) -Wall -g $^ $(LIBS) -o hidtest
20
21$(COBJS): %.o: %.c
22 $(CC) $(CFLAGS) $< -o $@
23
24clean:
25 rm -f *.o hidtest
26
27.PHONY: clean
diff --git a/contrib/SDL-3.2.8/src/hidapi/mac/Makefile.am b/contrib/SDL-3.2.8/src/hidapi/mac/Makefile.am
new file mode 100644
index 0000000..23d96e0
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/mac/Makefile.am
@@ -0,0 +1,9 @@
1lib_LTLIBRARIES = libhidapi.la
2libhidapi_la_SOURCES = hid.c
3libhidapi_la_LDFLAGS = $(LTLDFLAGS)
4AM_CPPFLAGS = -I$(top_srcdir)/hidapi/
5
6hdrdir = $(includedir)/hidapi
7hdr_HEADERS = $(top_srcdir)/hidapi/hidapi.h
8
9EXTRA_DIST = Makefile-manual
diff --git a/contrib/SDL-3.2.8/src/hidapi/mac/hid.c b/contrib/SDL-3.2.8/src/hidapi/mac/hid.c
new file mode 100644
index 0000000..8acb6da
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/mac/hid.c
@@ -0,0 +1,1594 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Copyright 2022, All Rights Reserved.
11
12 At the discretion of the user of this library,
13 this software may be licensed under the terms of the
14 GNU General Public License v3, a BSD-Style license, or the
15 original HIDAPI license as outlined in the LICENSE.txt,
16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17 files located at the root of the source distribution.
18 These files may also be found in the public source
19 code repository located at:
20 https://github.com/libusb/hidapi .
21********************************************************/
22
23/* See Apple Technical Note TN2187 for details on IOHidManager. */
24
25#include <IOKit/hid/IOHIDManager.h>
26#include <IOKit/hid/IOHIDKeys.h>
27#include <IOKit/IOKitLib.h>
28#include <IOKit/usb/USBSpec.h>
29#include <CoreFoundation/CoreFoundation.h>
30#include <mach/mach_error.h>
31#include <stdbool.h>
32#include <wchar.h>
33#include <locale.h>
34#include <pthread.h>
35#include <sys/time.h>
36#include <unistd.h>
37#include <dlfcn.h>
38
39#include "hidapi_darwin.h"
40
41/* Barrier implementation because Mac OSX doesn't have pthread_barrier.
42 It also doesn't have clock_gettime(). So much for POSIX and SUSv2.
43 This implementation came from Brent Priddy and was posted on
44 StackOverflow. It is used with his permission. */
45typedef int pthread_barrierattr_t;
46typedef struct pthread_barrier {
47 pthread_mutex_t mutex;
48 pthread_cond_t cond;
49 int count;
50 int trip_count;
51} pthread_barrier_t;
52
53static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
54{
55 (void) attr;
56
57 if (count == 0) {
58 errno = EINVAL;
59 return -1;
60 }
61
62 if (pthread_mutex_init(&barrier->mutex, 0) < 0) {
63 return -1;
64 }
65 if (pthread_cond_init(&barrier->cond, 0) < 0) {
66 pthread_mutex_destroy(&barrier->mutex);
67 return -1;
68 }
69 barrier->trip_count = count;
70 barrier->count = 0;
71
72 return 0;
73}
74
75static int pthread_barrier_destroy(pthread_barrier_t *barrier)
76{
77 pthread_cond_destroy(&barrier->cond);
78 pthread_mutex_destroy(&barrier->mutex);
79 return 0;
80}
81
82static int pthread_barrier_wait(pthread_barrier_t *barrier)
83{
84 pthread_mutex_lock(&barrier->mutex);
85 ++(barrier->count);
86 if (barrier->count >= barrier->trip_count) {
87 barrier->count = 0;
88 pthread_mutex_unlock(&barrier->mutex);
89 pthread_cond_broadcast(&barrier->cond);
90 return 1;
91 }
92 else {
93 do {
94 pthread_cond_wait(&barrier->cond, &(barrier->mutex));
95 }
96 while (barrier->count != 0);
97
98 pthread_mutex_unlock(&barrier->mutex);
99 return 0;
100 }
101}
102
103static int return_data(hid_device *dev, unsigned char *data, size_t length);
104
105/* Linked List of input reports received from the device. */
106struct input_report {
107 uint8_t *data;
108 size_t len;
109 struct input_report *next;
110};
111
112static struct hid_api_version api_version = {
113 .major = HID_API_VERSION_MAJOR,
114 .minor = HID_API_VERSION_MINOR,
115 .patch = HID_API_VERSION_PATCH
116};
117
118/* - Run context - */
119static IOHIDManagerRef hid_mgr = 0x0;
120static int is_macos_10_10_or_greater = 0;
121static IOOptionBits device_open_options = 0;
122static wchar_t *last_global_error_str = NULL;
123/* --- */
124
125struct hid_device_ {
126 IOHIDDeviceRef device_handle;
127 IOOptionBits open_options;
128 int blocking;
129 int disconnected;
130 CFStringRef run_loop_mode;
131 CFRunLoopRef run_loop;
132 CFRunLoopSourceRef source;
133 uint8_t *input_report_buf;
134 CFIndex max_input_report_len;
135 struct input_report *input_reports;
136 struct hid_device_info* device_info;
137
138 pthread_t thread;
139 pthread_mutex_t mutex; /* Protects input_reports */
140 pthread_cond_t condition;
141 pthread_barrier_t barrier; /* Ensures correct startup sequence */
142 pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */
143 int shutdown_thread;
144 wchar_t *last_error_str;
145};
146
147static hid_device *new_hid_device(void)
148{
149 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
150 if (dev == NULL) {
151 return NULL;
152 }
153
154 dev->device_handle = NULL;
155 dev->open_options = device_open_options;
156 dev->blocking = 1;
157 dev->disconnected = 0;
158 dev->run_loop_mode = NULL;
159 dev->run_loop = NULL;
160 dev->source = NULL;
161 dev->input_report_buf = NULL;
162 dev->input_reports = NULL;
163 dev->device_info = NULL;
164 dev->shutdown_thread = 0;
165 dev->last_error_str = NULL;
166
167 /* Thread objects */
168 pthread_mutex_init(&dev->mutex, NULL);
169 pthread_cond_init(&dev->condition, NULL);
170 pthread_barrier_init(&dev->barrier, NULL, 2);
171 pthread_barrier_init(&dev->shutdown_barrier, NULL, 2);
172
173 return dev;
174}
175
176static void free_hid_device(hid_device *dev)
177{
178 if (!dev)
179 return;
180
181 /* Delete any input reports still left over. */
182 struct input_report *rpt = dev->input_reports;
183 while (rpt) {
184 struct input_report *next = rpt->next;
185 free(rpt->data);
186 free(rpt);
187 rpt = next;
188 }
189
190 /* Free the string and the report buffer. The check for NULL
191 is necessary here as CFRelease() doesn't handle NULL like
192 free() and others do. */
193 if (dev->run_loop_mode)
194 CFRelease(dev->run_loop_mode);
195 if (dev->source)
196 CFRelease(dev->source);
197 free(dev->input_report_buf);
198 hid_free_enumeration(dev->device_info);
199
200 /* Clean up the thread objects */
201 pthread_barrier_destroy(&dev->shutdown_barrier);
202 pthread_barrier_destroy(&dev->barrier);
203 pthread_cond_destroy(&dev->condition);
204 pthread_mutex_destroy(&dev->mutex);
205
206 /* Free the structure itself. */
207 free(dev);
208}
209
210
211#ifndef HIDAPI_USING_SDL_RUNTIME
212/* The caller must free the returned string with free(). */
213static wchar_t *utf8_to_wchar_t(const char *utf8)
214{
215 wchar_t *ret = NULL;
216
217 if (utf8) {
218 size_t wlen = mbstowcs(NULL, utf8, 0);
219 if ((size_t) -1 == wlen) {
220 return wcsdup(L"");
221 }
222 ret = (wchar_t*) calloc(wlen+1, sizeof(wchar_t));
223 if (ret == NULL) {
224 /* as much as we can do at this point */
225 return NULL;
226 }
227 mbstowcs(ret, utf8, wlen+1);
228 ret[wlen] = 0x0000;
229 }
230
231 return ret;
232}
233#endif
234
235
236/* Makes a copy of the given error message (and decoded according to the
237 * currently locale) into the wide string pointer pointed by error_str.
238 * The last stored error string is freed.
239 * Use register_error_str(NULL) to free the error message completely. */
240static void register_error_str(wchar_t **error_str, const char *msg)
241{
242 free(*error_str);
243#ifdef HIDAPI_USING_SDL_RUNTIME
244 /* Thread-safe error handling */
245 if (msg) {
246 SDL_SetError("%s", msg);
247 } else {
248 SDL_ClearError();
249 }
250#else
251 *error_str = utf8_to_wchar_t(msg);
252#endif
253}
254
255/* Similar to register_error_str, but allows passing a format string with va_list args into this function. */
256static void register_error_str_vformat(wchar_t **error_str, const char *format, va_list args)
257{
258 char msg[1024];
259 vsnprintf(msg, sizeof(msg), format, args);
260
261 register_error_str(error_str, msg);
262}
263
264/* Set the last global error to be reported by hid_error(NULL).
265 * The given error message will be copied (and decoded according to the
266 * currently locale, so do not pass in string constants).
267 * The last stored global error message is freed.
268 * Use register_global_error(NULL) to indicate "no error". */
269static void register_global_error(const char *msg)
270{
271 register_error_str(&last_global_error_str, msg);
272}
273
274/* Similar to register_global_error, but allows passing a format string into this function. */
275static void register_global_error_format(const char *format, ...)
276{
277 va_list args;
278 va_start(args, format);
279 register_error_str_vformat(&last_global_error_str, format, args);
280 va_end(args);
281}
282
283/* Set the last error for a device to be reported by hid_error(dev).
284 * The given error message will be copied (and decoded according to the
285 * currently locale, so do not pass in string constants).
286 * The last stored device error message is freed.
287 * Use register_device_error(dev, NULL) to indicate "no error". */
288static void register_device_error(hid_device *dev, const char *msg)
289{
290 register_error_str(&dev->last_error_str, msg);
291}
292
293/* Similar to register_device_error, but you can pass a format string into this function. */
294static void register_device_error_format(hid_device *dev, const char *format, ...)
295{
296 va_list args;
297 va_start(args, format);
298 register_error_str_vformat(&dev->last_error_str, format, args);
299 va_end(args);
300}
301
302
303static CFArrayRef get_array_property(IOHIDDeviceRef device, CFStringRef key)
304{
305 CFTypeRef ref = IOHIDDeviceGetProperty(device, key);
306 if (ref != NULL && CFGetTypeID(ref) == CFArrayGetTypeID()) {
307 return (CFArrayRef)ref;
308 } else {
309 return NULL;
310 }
311}
312
313static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
314{
315 CFTypeRef ref;
316 int32_t value = 0;
317
318 ref = IOHIDDeviceGetProperty(device, key);
319 if (ref) {
320 if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
321 CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &value);
322 return value;
323 }
324 }
325 return 0;
326}
327
328static bool try_get_int_property(IOHIDDeviceRef device, CFStringRef key, int32_t *out_val)
329{
330 bool result = false;
331 CFTypeRef ref;
332
333 ref = IOHIDDeviceGetProperty(device, key);
334 if (ref) {
335 if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
336 result = CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, out_val);
337 }
338 }
339 return result;
340}
341
342static bool try_get_ioregistry_int_property(io_service_t service, CFStringRef property, int32_t *out_val)
343{
344 bool result = false;
345 CFTypeRef ref = IORegistryEntryCreateCFProperty(service, property, kCFAllocatorDefault, 0);
346
347 if (ref) {
348 if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
349 result = CFNumberGetValue(ref, kCFNumberSInt32Type, out_val);
350 }
351
352 CFRelease(ref);
353 }
354
355 return result;
356}
357
358static CFArrayRef get_usage_pairs(IOHIDDeviceRef device)
359{
360 return get_array_property(device, CFSTR(kIOHIDDeviceUsagePairsKey));
361}
362
363static unsigned short get_vendor_id(IOHIDDeviceRef device)
364{
365 return get_int_property(device, CFSTR(kIOHIDVendorIDKey));
366}
367
368static unsigned short get_product_id(IOHIDDeviceRef device)
369{
370 return get_int_property(device, CFSTR(kIOHIDProductIDKey));
371}
372
373static int32_t get_max_report_length(IOHIDDeviceRef device)
374{
375 return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey));
376}
377
378static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len)
379{
380 CFStringRef str;
381
382 if (!len)
383 return 0;
384
385 str = (CFStringRef) IOHIDDeviceGetProperty(device, prop);
386
387 buf[0] = 0;
388
389 if (str && CFGetTypeID(str) == CFStringGetTypeID()) {
390 CFIndex str_len = CFStringGetLength(str);
391 CFRange range;
392 CFIndex used_buf_len;
393 CFIndex chars_copied;
394
395 len --;
396
397 range.location = 0;
398 range.length = ((size_t) str_len > len)? len: (size_t) str_len;
399 chars_copied = CFStringGetBytes(str,
400 range,
401 kCFStringEncodingUTF32LE,
402 (char) '?',
403 FALSE,
404 (UInt8*)buf,
405 len * sizeof(wchar_t),
406 &used_buf_len);
407
408 if (chars_copied <= 0)
409 buf[0] = 0;
410 else
411 buf[chars_copied] = 0;
412
413 return 0;
414 }
415 else
416 return -1;
417
418}
419
420static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len)
421{
422 return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
423}
424
425static int get_manufacturer_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
426{
427 return get_string_property(device, CFSTR(kIOHIDManufacturerKey), buf, len);
428}
429
430static int get_product_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
431{
432 return get_string_property(device, CFSTR(kIOHIDProductKey), buf, len);
433}
434
435
436/* Implementation of wcsdup() for Mac. */
437static wchar_t *dup_wcs(const wchar_t *s)
438{
439 size_t len = wcslen(s);
440 wchar_t *ret = (wchar_t*) malloc((len+1)*sizeof(wchar_t));
441 wcscpy(ret, s);
442
443 return ret;
444}
445
446/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */
447static int init_hid_manager(void)
448{
449 /* Initialize all the HID Manager Objects */
450 hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
451 if (hid_mgr) {
452 IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
453 IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
454 return 0;
455 }
456
457 register_global_error("Failed to create IOHIDManager");
458 return -1;
459}
460
461HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void)
462{
463 return &api_version;
464}
465
466HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
467{
468 return HID_API_VERSION_STR;
469}
470
471/* Initialize the IOHIDManager if necessary. This is the public function, and
472 it is safe to call this function repeatedly. Return 0 for success and -1
473 for failure. */
474int HID_API_EXPORT hid_init(void)
475{
476 register_global_error(NULL);
477
478 if (!hid_mgr) {
479 is_macos_10_10_or_greater = (kCFCoreFoundationVersionNumber >= 1151.16); /* kCFCoreFoundationVersionNumber10_10 */
480 hid_darwin_set_open_exclusive(1); /* Backward compatibility */
481 return init_hid_manager();
482 }
483
484 /* Already initialized. */
485 return 0;
486}
487
488int HID_API_EXPORT hid_exit(void)
489{
490 if (hid_mgr) {
491 /* Close the HID manager. */
492 IOHIDManagerClose(hid_mgr, kIOHIDOptionsTypeNone);
493 CFRelease(hid_mgr);
494 hid_mgr = NULL;
495 }
496
497 /* Free global error message */
498 register_global_error(NULL);
499
500 return 0;
501}
502
503static void process_pending_events(void) {
504 SInt32 res;
505 do {
506 res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE);
507 } while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut);
508}
509
510static int read_usb_interface_from_hid_service_parent(io_service_t hid_service)
511{
512 int32_t result = -1;
513 bool success = false;
514 io_registry_entry_t current = IO_OBJECT_NULL;
515 kern_return_t res;
516 int parent_number = 0;
517
518 res = IORegistryEntryGetParentEntry(hid_service, kIOServicePlane, &current);
519 while (KERN_SUCCESS == res
520 /* Only search up to 3 parent entries.
521 * With the default driver - the parent-of-interest supposed to be the first one,
522 * but lets assume some custom drivers or so, with deeper tree. */
523 && parent_number < 3) {
524 io_registry_entry_t parent = IO_OBJECT_NULL;
525 int32_t interface_number = -1;
526 parent_number++;
527
528 success = try_get_ioregistry_int_property(current, CFSTR(kUSBInterfaceNumber), &interface_number);
529 if (success) {
530 result = interface_number;
531 break;
532 }
533
534 res = IORegistryEntryGetParentEntry(current, kIOServicePlane, &parent);
535 if (parent) {
536 IOObjectRelease(current);
537 current = parent;
538 }
539
540 }
541
542 if (current) {
543 IOObjectRelease(current);
544 current = IO_OBJECT_NULL;
545 }
546
547 return result;
548}
549
550#ifdef HIDAPI_IGNORE_DEVICE
551static hid_bus_type get_bus_type(IOHIDDeviceRef dev)
552{
553 hid_bus_type bus_type = HID_API_BUS_UNKNOWN;
554
555 CFTypeRef transport_prop = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDTransportKey));
556
557 if (transport_prop != NULL && CFGetTypeID(transport_prop) == CFStringGetTypeID()) {
558 if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportUSBValue), 0) == kCFCompareEqualTo) {
559 bus_type = HID_API_BUS_USB;
560 } else if (CFStringHasPrefix((CFStringRef)transport_prop, CFSTR(kIOHIDTransportBluetoothValue))) {
561 bus_type = HID_API_BUS_BLUETOOTH;
562 } else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportI2CValue), 0) == kCFCompareEqualTo) {
563 bus_type = HID_API_BUS_I2C;
564 } else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportSPIValue), 0) == kCFCompareEqualTo) {
565 bus_type = HID_API_BUS_SPI;
566 }
567 }
568 return bus_type;
569}
570#endif /* HIDAPI_IGNORE_DEVICE */
571
572static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, int32_t usage_page, int32_t usage)
573{
574 unsigned short dev_vid;
575 unsigned short dev_pid;
576 int BUF_LEN = 256;
577 wchar_t buf[BUF_LEN];
578 CFTypeRef transport_prop;
579
580 struct hid_device_info *cur_dev;
581 io_service_t hid_service;
582 kern_return_t res;
583 uint64_t entry_id = 0;
584
585 if (dev == NULL) {
586 return NULL;
587 }
588
589 cur_dev = (struct hid_device_info *)calloc(1, sizeof(struct hid_device_info));
590 if (cur_dev == NULL) {
591 return NULL;
592 }
593
594 dev_vid = get_vendor_id(dev);
595 dev_pid = get_product_id(dev);
596
597#ifdef HIDAPI_IGNORE_DEVICE
598 /* See if there are any devices we should skip in enumeration */
599 if (HIDAPI_IGNORE_DEVICE(get_bus_type(dev), dev_vid, dev_pid, usage_page, usage)) {
600 free(cur_dev);
601 return NULL;
602 }
603#endif
604
605 cur_dev->usage_page = usage_page;
606 cur_dev->usage = usage;
607
608 /* Fill out the record */
609 cur_dev->next = NULL;
610
611 /* Fill in the path (as a unique ID of the service entry) */
612 cur_dev->path = NULL;
613 hid_service = IOHIDDeviceGetService(dev);
614 if (hid_service != MACH_PORT_NULL) {
615 res = IORegistryEntryGetRegistryEntryID(hid_service, &entry_id);
616 }
617 else {
618 res = KERN_INVALID_ARGUMENT;
619 }
620
621 if (res == KERN_SUCCESS) {
622 /* max value of entry_id(uint64_t) is 18446744073709551615 which is 20 characters long,
623 so for (max) "path" string 'DevSrvsID:18446744073709551615' we would need
624 9+1+20+1=31 bytes buffer, but allocate 32 for simple alignment */
625 const size_t path_len = 32;
626 cur_dev->path = calloc(1, path_len);
627 if (cur_dev->path != NULL) {
628 snprintf(cur_dev->path, path_len, "DevSrvsID:%llu", entry_id);
629 }
630 }
631
632 if (cur_dev->path == NULL) {
633 /* for whatever reason, trying to keep it a non-NULL string */
634 cur_dev->path = strdup("");
635 }
636
637 /* Serial Number */
638 get_serial_number(dev, buf, BUF_LEN);
639 cur_dev->serial_number = dup_wcs(buf);
640
641 /* Manufacturer and Product strings */
642 get_manufacturer_string(dev, buf, BUF_LEN);
643 cur_dev->manufacturer_string = dup_wcs(buf);
644 get_product_string(dev, buf, BUF_LEN);
645 cur_dev->product_string = dup_wcs(buf);
646
647 /* VID/PID */
648 cur_dev->vendor_id = dev_vid;
649 cur_dev->product_id = dev_pid;
650
651 /* Release Number */
652 cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));
653
654 /* Interface Number.
655 * We can only retrieve the interface number for USB HID devices.
656 * See below */
657 cur_dev->interface_number = -1;
658
659 /* Bus Type */
660 transport_prop = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDTransportKey));
661
662 if (transport_prop != NULL && CFGetTypeID(transport_prop) == CFStringGetTypeID()) {
663 if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportUSBValue), 0) == kCFCompareEqualTo) {
664 int32_t interface_number = -1;
665 cur_dev->bus_type = HID_API_BUS_USB;
666
667 /* A IOHIDDeviceRef used to have this simple property,
668 * until macOS 13.3 - we will try to use it. */
669 if (try_get_int_property(dev, CFSTR(kUSBInterfaceNumber), &interface_number)) {
670 cur_dev->interface_number = interface_number;
671 } else {
672 /* Otherwise fallback to io_service_t property.
673 * (of one of the parent services). */
674 cur_dev->interface_number = read_usb_interface_from_hid_service_parent(hid_service);
675
676 /* If the above doesn't work -
677 * no (known) fallback exists at this point. */
678 }
679
680 /* Match "Bluetooth", "BluetoothLowEnergy" and "Bluetooth Low Energy" strings */
681 } else if (CFStringHasPrefix((CFStringRef)transport_prop, CFSTR(kIOHIDTransportBluetoothValue))) {
682 cur_dev->bus_type = HID_API_BUS_BLUETOOTH;
683 } else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportI2CValue), 0) == kCFCompareEqualTo) {
684 cur_dev->bus_type = HID_API_BUS_I2C;
685 } else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportSPIValue), 0) == kCFCompareEqualTo) {
686 cur_dev->bus_type = HID_API_BUS_SPI;
687 }
688 }
689
690 return cur_dev;
691}
692
693static struct hid_device_info *create_device_info(IOHIDDeviceRef device)
694{
695 const int32_t primary_usage_page = get_int_property(device, CFSTR(kIOHIDPrimaryUsagePageKey));
696 const int32_t primary_usage = get_int_property(device, CFSTR(kIOHIDPrimaryUsageKey));
697
698 /* Primary should always be first, to match previous behavior. */
699 struct hid_device_info *root = create_device_info_with_usage(device, primary_usage_page, primary_usage);
700 struct hid_device_info *cur = root;
701
702 CFArrayRef usage_pairs = get_usage_pairs(device);
703
704 if (usage_pairs != NULL) {
705 struct hid_device_info *next = NULL;
706 for (CFIndex i = 0; i < CFArrayGetCount(usage_pairs); i++) {
707 CFTypeRef dict = CFArrayGetValueAtIndex(usage_pairs, i);
708 if (CFGetTypeID(dict) != CFDictionaryGetTypeID()) {
709 continue;
710 }
711
712 CFTypeRef usage_page_ref, usage_ref;
713 int32_t usage_page, usage;
714
715 if (!CFDictionaryGetValueIfPresent((CFDictionaryRef)dict, CFSTR(kIOHIDDeviceUsagePageKey), &usage_page_ref) ||
716 !CFDictionaryGetValueIfPresent((CFDictionaryRef)dict, CFSTR(kIOHIDDeviceUsageKey), &usage_ref) ||
717 CFGetTypeID(usage_page_ref) != CFNumberGetTypeID() ||
718 CFGetTypeID(usage_ref) != CFNumberGetTypeID() ||
719 !CFNumberGetValue((CFNumberRef)usage_page_ref, kCFNumberSInt32Type, &usage_page) ||
720 !CFNumberGetValue((CFNumberRef)usage_ref, kCFNumberSInt32Type, &usage)) {
721 continue;
722 }
723 if (usage_page == primary_usage_page && usage == primary_usage)
724 continue; /* Already added. */
725
726 next = create_device_info_with_usage(device, usage_page, usage);
727 if (cur) {
728 if (next != NULL) {
729 cur->next = next;
730 cur = next;
731 }
732 } else {
733 root = cur = next;
734 }
735 }
736 }
737
738 return root;
739}
740
741struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
742{
743 struct hid_device_info *root = NULL; /* return object */
744 struct hid_device_info *cur_dev = NULL;
745 CFIndex num_devices;
746 int i;
747
748 /* Set up the HID Manager if it hasn't been done */
749 if (hid_init() < 0) {
750 return NULL;
751 }
752 /* register_global_error: global error is set/reset by hid_init */
753
754 /* give the IOHIDManager a chance to update itself */
755 process_pending_events();
756
757 /* Get a list of the Devices */
758 CFMutableDictionaryRef matching = NULL;
759 if (vendor_id != 0 || product_id != 0) {
760 matching = CFDictionaryCreateMutable(kCFAllocatorDefault, kIOHIDOptionsTypeNone, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
761
762 if (matching && vendor_id != 0) {
763 CFNumberRef v = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &vendor_id);
764 CFDictionarySetValue(matching, CFSTR(kIOHIDVendorIDKey), v);
765 CFRelease(v);
766 }
767
768 if (matching && product_id != 0) {
769 CFNumberRef p = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &product_id);
770 CFDictionarySetValue(matching, CFSTR(kIOHIDProductIDKey), p);
771 CFRelease(p);
772 }
773 }
774 IOHIDManagerSetDeviceMatching(hid_mgr, matching);
775 if (matching != NULL) {
776 CFRelease(matching);
777 }
778
779 CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
780
781 IOHIDDeviceRef *device_array = NULL;
782
783 if (device_set != NULL) {
784 /* Convert the list into a C array so we can iterate easily. */
785 num_devices = CFSetGetCount(device_set);
786 device_array = (IOHIDDeviceRef*) calloc(num_devices, sizeof(IOHIDDeviceRef));
787 CFSetGetValues(device_set, (const void **) device_array);
788 } else {
789 num_devices = 0;
790 }
791
792 /* Iterate over each device, making an entry for it. */
793 for (i = 0; i < num_devices; i++) {
794
795 IOHIDDeviceRef dev = device_array[i];
796 if (!dev) {
797 continue;
798 }
799
800 struct hid_device_info *tmp = create_device_info(dev);
801 if (tmp == NULL) {
802 continue;
803 }
804
805 if (cur_dev) {
806 cur_dev->next = tmp;
807 }
808 else {
809 root = tmp;
810 }
811 cur_dev = tmp;
812
813 /* move the pointer to the tail of returned list */
814 while (cur_dev->next != NULL) {
815 cur_dev = cur_dev->next;
816 }
817 }
818
819 free(device_array);
820 if (device_set != NULL)
821 CFRelease(device_set);
822
823 if (root == NULL) {
824 if (vendor_id == 0 && product_id == 0) {
825 register_global_error("No HID devices found in the system.");
826 } else {
827 register_global_error("No HID devices with requested VID/PID found in the system.");
828 }
829 }
830
831 return root;
832}
833
834void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
835{
836 /* This function is identical to the Linux version. Platform independent. */
837 struct hid_device_info *d = devs;
838 while (d) {
839 struct hid_device_info *next = d->next;
840 free(d->path);
841 free(d->serial_number);
842 free(d->manufacturer_string);
843 free(d->product_string);
844 free(d);
845 d = next;
846 }
847}
848
849hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
850{
851 /* This function is identical to the Linux version. Platform independent. */
852
853 struct hid_device_info *devs, *cur_dev;
854 const char *path_to_open = NULL;
855 hid_device * handle = NULL;
856
857 /* register_global_error: global error is reset by hid_enumerate/hid_init */
858 devs = hid_enumerate(vendor_id, product_id);
859 if (devs == NULL) {
860 /* register_global_error: global error is already set by hid_enumerate */
861 return NULL;
862 }
863
864 cur_dev = devs;
865 while (cur_dev) {
866 if (cur_dev->vendor_id == vendor_id &&
867 cur_dev->product_id == product_id) {
868 if (serial_number) {
869 if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
870 path_to_open = cur_dev->path;
871 break;
872 }
873 }
874 else {
875 path_to_open = cur_dev->path;
876 break;
877 }
878 }
879 cur_dev = cur_dev->next;
880 }
881
882 if (path_to_open) {
883 handle = hid_open_path(path_to_open);
884 } else {
885 register_global_error("Device with requested VID/PID/(SerialNumber) not found");
886 }
887
888 hid_free_enumeration(devs);
889
890 return handle;
891}
892
893static void hid_device_removal_callback(void *context, IOReturn result,
894 void *sender)
895{
896 (void) result;
897 (void) sender;
898
899 /* Stop the Run Loop for this device. */
900 hid_device *d = (hid_device*) context;
901
902 d->disconnected = 1;
903 CFRunLoopStop(d->run_loop);
904}
905
906/* The Run Loop calls this function for each input report received.
907 This function puts the data into a linked list to be picked up by
908 hid_read(). */
909static void hid_report_callback(void *context, IOReturn result, void *sender,
910 IOHIDReportType report_type, uint32_t report_id,
911 uint8_t *report, CFIndex report_length)
912{
913 (void) result;
914 (void) sender;
915 (void) report_type;
916 (void) report_id;
917
918 struct input_report *rpt;
919 hid_device *dev = (hid_device*) context;
920
921 /* Make a new Input Report object */
922 rpt = (struct input_report*) calloc(1, sizeof(struct input_report));
923 rpt->data = (uint8_t*) calloc(1, report_length);
924 memcpy(rpt->data, report, report_length);
925 rpt->len = report_length;
926 rpt->next = NULL;
927
928 /* Lock this section */
929 pthread_mutex_lock(&dev->mutex);
930
931 /* Attach the new report object to the end of the list. */
932 if (dev->input_reports == NULL) {
933 /* The list is empty. Put it at the root. */
934 dev->input_reports = rpt;
935 }
936 else {
937 /* Find the end of the list and attach. */
938 struct input_report *cur = dev->input_reports;
939 int num_queued = 0;
940 while (cur->next != NULL) {
941 cur = cur->next;
942 num_queued++;
943 }
944 cur->next = rpt;
945
946 /* Pop one off if we've reached 30 in the queue. This
947 way we don't grow forever if the user never reads
948 anything from the device. */
949 if (num_queued > 30) {
950 return_data(dev, NULL, 0);
951 }
952 }
953
954 /* Signal a waiting thread that there is data. */
955 pthread_cond_signal(&dev->condition);
956
957 /* Unlock */
958 pthread_mutex_unlock(&dev->mutex);
959
960}
961
962/* This gets called when the read_thread's run loop gets signaled by
963 hid_close(), and serves to stop the read_thread's run loop. */
964static void perform_signal_callback(void *context)
965{
966 hid_device *dev = (hid_device*) context;
967 CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/
968}
969
970static void *read_thread(void *param)
971{
972 hid_device *dev = (hid_device*) param;
973 SInt32 code;
974
975 /* Move the device's run loop to this thread. */
976 IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode);
977
978 /* Create the RunLoopSource which is used to signal the
979 event loop to stop when hid_close() is called. */
980 CFRunLoopSourceContext ctx;
981 memset(&ctx, 0, sizeof(ctx));
982 ctx.version = 0;
983 ctx.info = dev;
984 ctx.perform = &perform_signal_callback;
985 dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx);
986 CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode);
987
988 /* Store off the Run Loop so it can be stopped from hid_close()
989 and on device disconnection. */
990 dev->run_loop = CFRunLoopGetCurrent();
991
992 /* Notify the main thread that the read thread is up and running. */
993 pthread_barrier_wait(&dev->barrier);
994
995 /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
996 reports into the hid_report_callback(). */
997 while (!dev->shutdown_thread && !dev->disconnected) {
998 code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE);
999 /* Return if the device has been disconnected */
1000 if (code == kCFRunLoopRunFinished || code == kCFRunLoopRunStopped) {
1001 dev->disconnected = 1;
1002 break;
1003 }
1004
1005
1006 /* Break if The Run Loop returns Finished or Stopped. */
1007 if (code != kCFRunLoopRunTimedOut &&
1008 code != kCFRunLoopRunHandledSource) {
1009 /* There was some kind of error. Setting
1010 shutdown seems to make sense, but
1011 there may be something else more appropriate */
1012 dev->shutdown_thread = 1;
1013 break;
1014 }
1015 }
1016
1017 /* Now that the read thread is stopping, Wake any threads which are
1018 waiting on data (in hid_read_timeout()). Do this under a mutex to
1019 make sure that a thread which is about to go to sleep waiting on
1020 the condition actually will go to sleep before the condition is
1021 signaled. */
1022 pthread_mutex_lock(&dev->mutex);
1023 pthread_cond_broadcast(&dev->condition);
1024 pthread_mutex_unlock(&dev->mutex);
1025
1026 /* Wait here until hid_close() is called and makes it past
1027 the call to CFRunLoopWakeUp(). This thread still needs to
1028 be valid when that function is called on the other thread. */
1029 pthread_barrier_wait(&dev->shutdown_barrier);
1030
1031 return NULL;
1032}
1033
1034/* \p path must be one of:
1035 - in format 'DevSrvsID:<RegistryEntryID>' (as returned by hid_enumerate);
1036 - a valid path to an IOHIDDevice in the IOService plane (as returned by IORegistryEntryGetPath,
1037 e.g.: "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/EHC1@1D,7/AppleUSBEHCI/PLAYSTATION(R)3 Controller@fd120000/IOUSBInterface@0/IOUSBHIDDriver");
1038 Second format is for compatibility with paths accepted by older versions of HIDAPI.
1039*/
1040static io_registry_entry_t hid_open_service_registry_from_path(const char *path)
1041{
1042 if (path == NULL)
1043 return MACH_PORT_NULL;
1044
1045 /* Get the IORegistry entry for the given path */
1046 if (strncmp("DevSrvsID:", path, 10) == 0) {
1047 char *endptr;
1048 uint64_t entry_id = strtoull(path + 10, &endptr, 10);
1049 if (*endptr == '\0') {
1050 return IOServiceGetMatchingService((mach_port_t) 0, IORegistryEntryIDMatching(entry_id));
1051 }
1052 }
1053 else {
1054 /* Fallback to older format of the path */
1055 return IORegistryEntryFromPath((mach_port_t) 0, path);
1056 }
1057
1058 return MACH_PORT_NULL;
1059}
1060
1061hid_device * HID_API_EXPORT hid_open_path(const char *path)
1062{
1063 hid_device *dev = NULL;
1064 io_registry_entry_t entry = MACH_PORT_NULL;
1065 IOReturn ret = kIOReturnInvalid;
1066 char str[32];
1067
1068 /* Set up the HID Manager if it hasn't been done */
1069 if (hid_init() < 0) {
1070 return NULL;
1071 }
1072 /* register_global_error: global error is set/reset by hid_init */
1073
1074 dev = new_hid_device();
1075 if (!dev) {
1076 register_global_error("Couldn't allocate memory");
1077 return NULL;
1078 }
1079
1080 /* Get the IORegistry entry for the given path */
1081 entry = hid_open_service_registry_from_path(path);
1082 if (entry == MACH_PORT_NULL) {
1083 /* Path wasn't valid (maybe device was removed?) */
1084 register_global_error("hid_open_path: device mach entry not found with the given path");
1085 goto return_error;
1086 }
1087
1088 /* Create an IOHIDDevice for the entry */
1089 dev->device_handle = IOHIDDeviceCreate(kCFAllocatorDefault, entry);
1090 if (dev->device_handle == NULL) {
1091 /* Error creating the HID device */
1092 register_global_error("hid_open_path: failed to create IOHIDDevice from the mach entry");
1093 goto return_error;
1094 }
1095
1096 /* Open the IOHIDDevice */
1097 ret = IOHIDDeviceOpen(dev->device_handle, dev->open_options);
1098 if (ret != kIOReturnSuccess) {
1099 register_global_error_format("hid_open_path: failed to open IOHIDDevice from mach entry: (0x%08X) %s", ret, mach_error_string(ret));
1100 goto return_error;
1101 }
1102
1103 /* Create the buffers for receiving data */
1104 dev->max_input_report_len = (CFIndex) get_max_report_length(dev->device_handle);
1105 dev->input_report_buf = (uint8_t*) calloc(dev->max_input_report_len, sizeof(uint8_t));
1106
1107 /* Create the Run Loop Mode for this device.
1108 printing the reference seems to work. */
1109 snprintf(str, sizeof(str), "HIDAPI_%p", (void*) dev->device_handle);
1110 dev->run_loop_mode =
1111 CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII);
1112
1113 /* Attach the device to a Run Loop */
1114 IOHIDDeviceRegisterInputReportCallback(
1115 dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
1116 &hid_report_callback, dev);
1117 IOHIDDeviceRegisterRemovalCallback(dev->device_handle, hid_device_removal_callback, dev);
1118
1119 /* Start the read thread */
1120 pthread_create(&dev->thread, NULL, read_thread, dev);
1121
1122 /* Wait here for the read thread to be initialized. */
1123 pthread_barrier_wait(&dev->barrier);
1124
1125 IOObjectRelease(entry);
1126 return dev;
1127
1128return_error:
1129 if (dev->device_handle != NULL)
1130 CFRelease(dev->device_handle);
1131
1132 if (entry != MACH_PORT_NULL)
1133 IOObjectRelease(entry);
1134
1135 free_hid_device(dev);
1136 return NULL;
1137}
1138
1139static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char *data, size_t length)
1140{
1141 const unsigned char *data_to_send = data;
1142 CFIndex length_to_send = length;
1143 IOReturn res;
1144 unsigned char report_id;
1145
1146 register_device_error(dev, NULL);
1147
1148 if (!data || (length == 0)) {
1149 register_device_error(dev, strerror(EINVAL));
1150 return -1;
1151 }
1152
1153 report_id = data[0];
1154
1155 if (report_id == 0x0) {
1156 /* Not using numbered Reports.
1157 Don't send the report number. */
1158 data_to_send = data+1;
1159 length_to_send = length-1;
1160 }
1161
1162 /* Avoid crash if the device has been unplugged. */
1163 if (dev->disconnected) {
1164 register_device_error(dev, "Device is disconnected");
1165 return -1;
1166 }
1167
1168 res = IOHIDDeviceSetReport(dev->device_handle,
1169 type,
1170 report_id,
1171 data_to_send, length_to_send);
1172
1173 if (res != kIOReturnSuccess) {
1174 register_device_error_format(dev, "IOHIDDeviceSetReport failed: (0x%08X) %s", res, mach_error_string(res));
1175 return -1;
1176 }
1177
1178 return (int) length;
1179}
1180
1181static int get_report(hid_device *dev, IOHIDReportType type, unsigned char *data, size_t length)
1182{
1183 unsigned char *report = data;
1184 CFIndex report_length = length;
1185 IOReturn res = kIOReturnSuccess;
1186 const unsigned char report_id = data[0];
1187
1188 register_device_error(dev, NULL);
1189
1190 if (report_id == 0x0) {
1191 /* Not using numbered Reports.
1192 Don't send the report number. */
1193 report = data+1;
1194 report_length = length-1;
1195 }
1196
1197 /* Avoid crash if the device has been unplugged. */
1198 if (dev->disconnected) {
1199 register_device_error(dev, "Device is disconnected");
1200 return -1;
1201 }
1202
1203 res = IOHIDDeviceGetReport(dev->device_handle,
1204 type,
1205 report_id,
1206 report, &report_length);
1207
1208 if (res != kIOReturnSuccess) {
1209 register_device_error_format(dev, "IOHIDDeviceGetReport failed: (0x%08X) %s", res, mach_error_string(res));
1210 return -1;
1211 }
1212
1213 if (report_id == 0x0) { /* 0 report number still present at the beginning */
1214 report_length++;
1215 }
1216
1217 return (int) report_length;
1218}
1219
1220int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
1221{
1222 return set_report(dev, kIOHIDReportTypeOutput, data, length);
1223}
1224
1225/* Helper function, so that this isn't duplicated in hid_read(). */
1226static int return_data(hid_device *dev, unsigned char *data, size_t length)
1227{
1228 /* Copy the data out of the linked list item (rpt) into the
1229 return buffer (data), and delete the liked list item. */
1230 struct input_report *rpt = dev->input_reports;
1231 size_t len = (length < rpt->len)? length: rpt->len;
1232 if (data != NULL) {
1233 memcpy(data, rpt->data, len);
1234 }
1235 dev->input_reports = rpt->next;
1236 free(rpt->data);
1237 free(rpt);
1238 return (int) len;
1239}
1240
1241static int cond_wait(hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex)
1242{
1243 while (!dev->input_reports) {
1244 int res = pthread_cond_wait(cond, mutex);
1245 if (res != 0)
1246 return res;
1247
1248 /* A res of 0 means we may have been signaled or it may
1249 be a spurious wakeup. Check to see that there's actually
1250 data in the queue before returning, and if not, go back
1251 to sleep. See the pthread_cond_timedwait() man page for
1252 details. */
1253
1254 if (dev->shutdown_thread || dev->disconnected) {
1255 return -1;
1256 }
1257 }
1258
1259 return 0;
1260}
1261
1262static int cond_timedwait(hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
1263{
1264 while (!dev->input_reports) {
1265 int res = pthread_cond_timedwait(cond, mutex, abstime);
1266 if (res != 0)
1267 return res;
1268
1269 /* A res of 0 means we may have been signaled or it may
1270 be a spurious wakeup. Check to see that there's actually
1271 data in the queue before returning, and if not, go back
1272 to sleep. See the pthread_cond_timedwait() man page for
1273 details. */
1274
1275 if (dev->shutdown_thread || dev->disconnected) {
1276 return -1;
1277 }
1278 }
1279
1280 return 0;
1281
1282}
1283
1284int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1285{
1286 int bytes_read = -1;
1287
1288 /* Lock the access to the report list. */
1289 pthread_mutex_lock(&dev->mutex);
1290
1291 /* There's an input report queued up. Return it. */
1292 if (dev->input_reports) {
1293 /* Return the first one */
1294 bytes_read = return_data(dev, data, length);
1295 goto ret;
1296 }
1297
1298 /* Return if the device has been disconnected. */
1299 if (dev->disconnected) {
1300 bytes_read = -1;
1301 register_device_error(dev, "hid_read_timeout: device disconnected");
1302 goto ret;
1303 }
1304
1305 if (dev->shutdown_thread) {
1306 /* This means the device has been closed (or there
1307 has been an error. An error code of -1 should
1308 be returned. */
1309 bytes_read = -1;
1310 register_device_error(dev, "hid_read_timeout: thread shutdown");
1311 goto ret;
1312 }
1313
1314 /* There is no data. Go to sleep and wait for data. */
1315
1316 if (milliseconds == -1) {
1317 /* Blocking */
1318 int res;
1319 res = cond_wait(dev, &dev->condition, &dev->mutex);
1320 if (res == 0)
1321 bytes_read = return_data(dev, data, length);
1322 else {
1323 /* There was an error, or a device disconnection. */
1324 register_device_error(dev, "hid_read_timeout: error waiting for more data");
1325 bytes_read = -1;
1326 }
1327 }
1328 else if (milliseconds > 0) {
1329 /* Non-blocking, but called with timeout. */
1330 int res;
1331 struct timespec ts;
1332 struct timeval tv;
1333 gettimeofday(&tv, NULL);
1334 TIMEVAL_TO_TIMESPEC(&tv, &ts);
1335 ts.tv_sec += milliseconds / 1000;
1336 ts.tv_nsec += (milliseconds % 1000) * 1000000;
1337 if (ts.tv_nsec >= 1000000000L) {
1338 ts.tv_sec++;
1339 ts.tv_nsec -= 1000000000L;
1340 }
1341
1342 res = cond_timedwait(dev, &dev->condition, &dev->mutex, &ts);
1343 if (res == 0) {
1344 bytes_read = return_data(dev, data, length);
1345 } else if (res == ETIMEDOUT) {
1346 bytes_read = 0;
1347 } else {
1348 register_device_error(dev, "hid_read_timeout: error waiting for more data");
1349 bytes_read = -1;
1350 }
1351 }
1352 else {
1353 /* Purely non-blocking */
1354 bytes_read = 0;
1355 }
1356
1357ret:
1358 /* Unlock */
1359 pthread_mutex_unlock(&dev->mutex);
1360 return bytes_read;
1361}
1362
1363int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
1364{
1365 return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
1366}
1367
1368int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
1369{
1370 /* All Nonblocking operation is handled by the library. */
1371 dev->blocking = !nonblock;
1372
1373 return 0;
1374}
1375
1376int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
1377{
1378 return set_report(dev, kIOHIDReportTypeFeature, data, length);
1379}
1380
1381int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
1382{
1383 return get_report(dev, kIOHIDReportTypeFeature, data, length);
1384}
1385
1386int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
1387{
1388 return get_report(dev, kIOHIDReportTypeInput, data, length);
1389}
1390
1391void HID_API_EXPORT hid_close(hid_device *dev)
1392{
1393 if (!dev)
1394 return;
1395
1396 /* Disconnect the report callback before close.
1397 See comment below.
1398 */
1399 if (is_macos_10_10_or_greater || !dev->disconnected) {
1400 IOHIDDeviceRegisterInputReportCallback(
1401 dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
1402 NULL, dev);
1403 IOHIDDeviceRegisterRemovalCallback(dev->device_handle, NULL, dev);
1404 IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode);
1405 IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
1406 }
1407
1408 /* Cause read_thread() to stop. */
1409 dev->shutdown_thread = 1;
1410
1411 /* Wake up the run thread's event loop so that the thread can exit. */
1412 CFRunLoopSourceSignal(dev->source);
1413 CFRunLoopWakeUp(dev->run_loop);
1414
1415 /* Notify the read thread that it can shut down now. */
1416 pthread_barrier_wait(&dev->shutdown_barrier);
1417
1418 /* Wait for read_thread() to end. */
1419 pthread_join(dev->thread, NULL);
1420
1421 /* Close the OS handle to the device, but only if it's not
1422 been unplugged. If it's been unplugged, then calling
1423 IOHIDDeviceClose() will crash.
1424
1425 UPD: The crash part was true in/until some version of macOS.
1426 Starting with macOS 10.15, there is an opposite effect in some environments:
1427 crash happenes if IOHIDDeviceClose() is not called.
1428 Not leaking a resource in all tested environments.
1429 */
1430 if (is_macos_10_10_or_greater || !dev->disconnected) {
1431 IOHIDDeviceClose(dev->device_handle, dev->open_options);
1432 }
1433
1434 /* Clear out the queue of received reports. */
1435 pthread_mutex_lock(&dev->mutex);
1436 while (dev->input_reports) {
1437 return_data(dev, NULL, 0);
1438 }
1439 pthread_mutex_unlock(&dev->mutex);
1440 CFRelease(dev->device_handle);
1441
1442 free_hid_device(dev);
1443}
1444
1445int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
1446{
1447 if (!string || !maxlen)
1448 {
1449 register_device_error(dev, "Zero buffer/length");
1450 return -1;
1451 }
1452
1453 struct hid_device_info *info = hid_get_device_info(dev);
1454 if (!info)
1455 {
1456 // hid_get_device_info will have set an error already
1457 return -1;
1458 }
1459
1460 wcsncpy(string, info->manufacturer_string, maxlen);
1461 string[maxlen - 1] = L'\0';
1462
1463 return 0;
1464}
1465
1466int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
1467{
1468 if (!string || !maxlen) {
1469 register_device_error(dev, "Zero buffer/length");
1470 return -1;
1471 }
1472
1473 struct hid_device_info *info = hid_get_device_info(dev);
1474 if (!info) {
1475 // hid_get_device_info will have set an error already
1476 return -1;
1477 }
1478
1479 wcsncpy(string, info->product_string, maxlen);
1480 string[maxlen - 1] = L'\0';
1481
1482 return 0;
1483}
1484
1485int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1486{
1487 if (!string || !maxlen) {
1488 register_device_error(dev, "Zero buffer/length");
1489 return -1;
1490 }
1491
1492 struct hid_device_info *info = hid_get_device_info(dev);
1493 if (!info) {
1494 // hid_get_device_info will have set an error already
1495 return -1;
1496 }
1497
1498 wcsncpy(string, info->serial_number, maxlen);
1499 string[maxlen - 1] = L'\0';
1500
1501 return 0;
1502}
1503
1504HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_device *dev) {
1505 if (!dev->device_info) {
1506 dev->device_info = create_device_info(dev->device_handle);
1507 if (!dev->device_info) {
1508 register_device_error(dev, "Failed to create hid_device_info");
1509 }
1510 }
1511
1512 return dev->device_info;
1513}
1514
1515int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1516{
1517 (void) dev;
1518 (void) string_index;
1519 (void) string;
1520 (void) maxlen;
1521
1522 register_device_error(dev, "hid_get_indexed_string: not available on this platform");
1523 return -1;
1524}
1525
1526int HID_API_EXPORT_CALL hid_darwin_get_location_id(hid_device *dev, uint32_t *location_id)
1527{
1528 int res = get_int_property(dev->device_handle, CFSTR(kIOHIDLocationIDKey));
1529 if (res != 0) {
1530 *location_id = (uint32_t) res;
1531 return 0;
1532 } else {
1533 register_device_error(dev, "Failed to get IOHIDLocationID property");
1534 return -1;
1535 }
1536}
1537
1538void HID_API_EXPORT_CALL hid_darwin_set_open_exclusive(int open_exclusive)
1539{
1540 device_open_options = (open_exclusive == 0) ? kIOHIDOptionsTypeNone : kIOHIDOptionsTypeSeizeDevice;
1541}
1542
1543int HID_API_EXPORT_CALL hid_darwin_get_open_exclusive(void)
1544{
1545 return (device_open_options == kIOHIDOptionsTypeSeizeDevice) ? 1 : 0;
1546}
1547
1548int HID_API_EXPORT_CALL hid_darwin_is_device_open_exclusive(hid_device *dev)
1549{
1550 if (!dev)
1551 return -1;
1552
1553 return (dev->open_options == kIOHIDOptionsTypeSeizeDevice) ? 1 : 0;
1554}
1555
1556int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
1557{
1558 CFTypeRef ref = IOHIDDeviceGetProperty(dev->device_handle, CFSTR(kIOHIDReportDescriptorKey));
1559 if (ref != NULL && CFGetTypeID(ref) == CFDataGetTypeID()) {
1560 CFDataRef report_descriptor = (CFDataRef) ref;
1561 const UInt8 *descriptor_buf = CFDataGetBytePtr(report_descriptor);
1562 CFIndex descriptor_buf_len = CFDataGetLength(report_descriptor);
1563 size_t copy_len = (size_t) descriptor_buf_len;
1564
1565 if (descriptor_buf == NULL || descriptor_buf_len < 0) {
1566 register_device_error(dev, "Zero buffer/length");
1567 return -1;
1568 }
1569
1570 if (buf_size < copy_len) {
1571 copy_len = buf_size;
1572 }
1573
1574 memcpy(buf, descriptor_buf, copy_len);
1575 return (int)copy_len;
1576 }
1577 else {
1578 register_device_error(dev, "Failed to get kIOHIDReportDescriptorKey property");
1579 return -1;
1580 }
1581}
1582
1583HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
1584{
1585 if (dev) {
1586 if (dev->last_error_str == NULL)
1587 return L"Success";
1588 return dev->last_error_str;
1589 }
1590
1591 if (last_global_error_str == NULL)
1592 return L"Success";
1593 return last_global_error_str;
1594}
diff --git a/contrib/SDL-3.2.8/src/hidapi/mac/hidapi_darwin.h b/contrib/SDL-3.2.8/src/hidapi/mac/hidapi_darwin.h
new file mode 100644
index 0000000..1465583
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/mac/hidapi_darwin.h
@@ -0,0 +1,98 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19
20/** @file
21 * @defgroup API hidapi API
22
23 * Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
24 */
25
26#ifndef HIDAPI_DARWIN_H__
27#define HIDAPI_DARWIN_H__
28
29#include <stdint.h>
30
31#include "../hidapi/hidapi.h"
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37 /** @brief Get the location ID for a HID device.
38
39 Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
40
41 @ingroup API
42 @param dev A device handle returned from hid_open().
43 @param location_id The device's location ID on return.
44
45 @returns
46 This function returns 0 on success and -1 on error.
47 */
48 int HID_API_EXPORT_CALL hid_darwin_get_location_id(hid_device *dev, uint32_t *location_id);
49
50
51 /** @brief Changes the behavior of all further calls to @ref hid_open or @ref hid_open_path.
52
53 By default on Darwin platform all devices opened by HIDAPI with @ref hid_open or @ref hid_open_path
54 are opened in exclusive mode (see kIOHIDOptionsTypeSeizeDevice).
55
56 Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
57
58 @ingroup API
59 @param open_exclusive When set to 0 - all further devices will be opened
60 in non-exclusive mode. Otherwise - all further devices will be opened
61 in exclusive mode.
62
63 @note During the initialisation by @ref hid_init - this property is set to 1 (TRUE).
64 This is done to preserve full backward compatibility with previous behavior.
65
66 @note Calling this function before @ref hid_init or after @ref hid_exit has no effect.
67 */
68 void HID_API_EXPORT_CALL hid_darwin_set_open_exclusive(int open_exclusive);
69
70 /** @brief Getter for option set by @ref hid_darwin_set_open_exclusive.
71
72 Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
73
74 @ingroup API
75 @return 1 if all further devices will be opened in exclusive mode.
76
77 @note Value returned by this function before calling to @ref hid_init or after @ref hid_exit
78 is not reliable.
79 */
80 int HID_API_EXPORT_CALL hid_darwin_get_open_exclusive(void);
81
82 /** @brief Check how the device was opened.
83
84 Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
85
86 @ingroup API
87 @param dev A device to get property from.
88
89 @return 1 if the device is opened in exclusive mode, 0 - opened in non-exclusive,
90 -1 - if dev is invalid.
91 */
92 int HID_API_EXPORT_CALL hid_darwin_is_device_open_exclusive(hid_device *dev);
93
94#ifdef __cplusplus
95}
96#endif
97
98#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/meson.build b/contrib/SDL-3.2.8/src/hidapi/meson.build
new file mode 100644
index 0000000..d7867cb
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/meson.build
@@ -0,0 +1,22 @@
1project('hidapi', meson_version: '>=0.57.0', version: files('VERSION'))
2
3cmake = import('cmake')
4
5hidapi_build_options = cmake.subproject_options()
6hidapi_build_options.set_install(true)
7
8hidapi_build = cmake.subproject('hidapi_build_cmake', options: hidapi_build_options)
9
10if (hidapi_build.target_list().contains('hidapi_winapi'))
11 hidapi_winapi_dep = hidapi_build.dependency('hidapi_winapi')
12 hidapi_dep = hidapi_winapi_dep
13elif (hidapi_build.target_list().contains('hidapi_darwin'))
14 hidapi_darwin_dep = hidapi_build.dependency('hidapi_darwin')
15 hidapi_dep = hidapi_darwin_dep
16elif (hidapi_build.target_list().contains('hidapi_hidraw'))
17 hidapi_hidraw_dep = hidapi_build.dependency('hidapi_hidraw')
18 hidapi_dep = hidapi_hidraw_dep
19elif (hidapi_build.target_list().contains('hidapi_libusb'))
20 hidapi_libusb_dep = hidapi_build.dependency('hidapi_libusb')
21 hidapi_dep = hidapi_libusb_dep
22endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/netbsd/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/netbsd/CMakeLists.txt
new file mode 100644
index 0000000..3b3e4d0
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/netbsd/CMakeLists.txt
@@ -0,0 +1,35 @@
1cmake_minimum_required(VERSION 3.6.3...3.25 FATAL_ERROR)
2
3add_library(hidapi_netbsd
4 ${HIDAPI_PUBLIC_HEADERS}
5 hid.c
6)
7target_link_libraries(hidapi_netbsd PUBLIC hidapi_include)
8
9find_package(Threads REQUIRED)
10
11target_link_libraries(hidapi_netbsd PRIVATE Threads::Threads)
12
13set_target_properties(hidapi_netbsd
14 PROPERTIES
15 EXPORT_NAME "netbsd"
16 OUTPUT_NAME "hidapi-netbsd"
17 VERSION ${PROJECT_VERSION}
18 SOVERSION ${PROJECT_VERSION_MAJOR}
19 PUBLIC_HEADER "${HIDAPI_PUBLIC_HEADERS}"
20)
21
22# compatibility with find_package()
23add_library(hidapi::netbsd ALIAS hidapi_netbsd)
24# compatibility with raw library link
25add_library(hidapi-netbsd ALIAS hidapi_netbsd)
26
27if(HIDAPI_INSTALL_TARGETS)
28 install(TARGETS hidapi_netbsd EXPORT hidapi
29 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
30 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
31 PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/hidapi"
32 )
33endif()
34
35hidapi_configure_pc("${PROJECT_ROOT}/pc/hidapi-netbsd.pc.in")
diff --git a/contrib/SDL-3.2.8/src/hidapi/netbsd/README.md b/contrib/SDL-3.2.8/src/hidapi/netbsd/README.md
new file mode 100644
index 0000000..f1b12a0
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/netbsd/README.md
@@ -0,0 +1,29 @@
1Implementation Notes
2--------------------
3NetBSD maps every `uhidev` device to one or more `uhid`
4devices. Each `uhid` device only supports one report ID.
5The parent device `uhidev` creates one `uhid` device per
6report ID found in the hardware's report descriptor.
7
8In the event there are no report ID(s) found within the
9report descriptor, only one `uhid` device with a report ID
10of `0` is created.
11
12In order to remain compatible with existing `hidapi` APIs,
13all the `uhid` devices created by the parent `uhidev` device
14must be opened under the same `hid_device` instance to ensure
15that we can route reports to their appropriate `uhid` device.
16
17Internally the `uhid` driver will insert the report ID as
18needed so we must also omit the report ID in any situation
19where the `hidapi` API expects it to be included in the
20report data stream.
21
22Given the design of `uhid`, it must be augmented with extra
23platform specific APIs to ensure that the exact relationship
24between `uhidev` devices and `uhid` devices can be determined.
25
26The NetBSD implementation does this via the `drvctl` kernel
27driver. At present there is no known way to do this on OpenBSD
28for a `uhid` implementation to be at the same level as the
29NetBSD one.
diff --git a/contrib/SDL-3.2.8/src/hidapi/netbsd/hid.c b/contrib/SDL-3.2.8/src/hidapi/netbsd/hid.c
new file mode 100644
index 0000000..82f34d4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/netbsd/hid.c
@@ -0,0 +1,1173 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 James Buren
6 libusb/hidapi Team
7
8 Copyright 2023, All Rights Reserved.
9
10 At the discretion of the user of this library,
11 this software may be licensed under the terms of the
12 GNU General Public License v3, a BSD-Style license, or the
13 original HIDAPI license as outlined in the LICENSE.txt,
14 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
15 files located at the root of the source distribution.
16 These files may also be found in the public source
17 code repository located at:
18 https://github.com/libusb/hidapi .
19********************************************************/
20
21/* C */
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <locale.h>
26#include <ctype.h>
27#include <errno.h>
28
29/* Unix */
30#include <unistd.h>
31#include <fcntl.h>
32#include <iconv.h>
33#include <poll.h>
34
35/* NetBSD */
36#include <sys/drvctlio.h>
37#include <dev/usb/usb.h>
38#include <dev/usb/usbhid.h>
39
40#include "../hidapi/hidapi.h"
41
42#define HIDAPI_MAX_CHILD_DEVICES 256
43
44struct hid_device_ {
45 int device_handle;
46 int blocking;
47 wchar_t *last_error_str;
48 struct hid_device_info *device_info;
49 size_t poll_handles_length;
50 struct pollfd poll_handles[256];
51 int report_handles[256];
52 char path[USB_MAX_DEVNAMELEN];
53};
54
55struct hid_enumerate_data {
56 struct hid_device_info *root;
57 struct hid_device_info *end;
58 int drvctl;
59 uint16_t vendor_id;
60 uint16_t product_id;
61};
62
63typedef void (*enumerate_devices_callback) (const struct usb_device_info *, void *);
64
65static wchar_t *last_global_error_str = NULL;
66
67/* The caller must free the returned string with free(). */
68static wchar_t *utf8_to_wchar_t(const char *utf8)
69{
70 wchar_t *ret = NULL;
71
72 if (utf8) {
73 size_t wlen = mbstowcs(NULL, utf8, 0);
74 if ((size_t) -1 == wlen) {
75 return wcsdup(L"");
76 }
77 ret = (wchar_t*) calloc(wlen+1, sizeof(wchar_t));
78 if (ret == NULL) {
79 /* as much as we can do at this point */
80 return NULL;
81 }
82 mbstowcs(ret, utf8, wlen+1);
83 ret[wlen] = 0x0000;
84 }
85
86 return ret;
87}
88
89/* Makes a copy of the given error message (and decoded according to the
90 * currently locale) into the wide string pointer pointed by error_str.
91 * The last stored error string is freed.
92 * Use register_error_str(NULL) to free the error message completely. */
93static void register_error_str(wchar_t **error_str, const char *msg)
94{
95 free(*error_str);
96 *error_str = utf8_to_wchar_t(msg);
97}
98
99/* Semilar to register_error_str, but allows passing a format string with va_list args into this function. */
100static void register_error_str_vformat(wchar_t **error_str, const char *format, va_list args)
101{
102 char msg[256];
103 vsnprintf(msg, sizeof(msg), format, args);
104
105 register_error_str(error_str, msg);
106}
107
108/* Set the last global error to be reported by hid_error(NULL).
109 * The given error message will be copied (and decoded according to the
110 * currently locale, so do not pass in string constants).
111 * The last stored global error message is freed.
112 * Use register_global_error(NULL) to indicate "no error". */
113static void register_global_error(const char *msg)
114{
115 register_error_str(&last_global_error_str, msg);
116}
117
118/* Similar to register_global_error, but allows passing a format string into this function. */
119static void register_global_error_format(const char *format, ...)
120{
121 va_list args;
122 va_start(args, format);
123 register_error_str_vformat(&last_global_error_str, format, args);
124 va_end(args);
125}
126
127/* Set the last error for a device to be reported by hid_error(dev).
128 * The given error message will be copied (and decoded according to the
129 * currently locale, so do not pass in string constants).
130 * The last stored device error message is freed.
131 * Use register_device_error(dev, NULL) to indicate "no error". */
132static void register_device_error(hid_device *dev, const char *msg)
133{
134 register_error_str(&dev->last_error_str, msg);
135}
136
137/* Similar to register_device_error, but you can pass a format string into this function. */
138static void register_device_error_format(hid_device *dev, const char *format, ...)
139{
140 va_list args;
141 va_start(args, format);
142 register_error_str_vformat(&dev->last_error_str, format, args);
143 va_end(args);
144}
145
146
147/*
148 * Gets the size of the HID item at the given position
149 * Returns 1 if successful, 0 if an invalid key
150 * Sets data_len and key_size when successful
151 */
152static int get_hid_item_size(const uint8_t *report_descriptor, uint32_t size, unsigned int pos, int *data_len, int *key_size)
153{
154 int key = report_descriptor[pos];
155 int size_code;
156
157 /*
158 * This is a Long Item. The next byte contains the
159 * length of the data section (value) for this key.
160 * See the HID specification, version 1.11, section
161 * 6.2.2.3, titled "Long Items."
162 */
163 if ((key & 0xf0) == 0xf0) {
164 if (pos + 1 < size)
165 {
166 *data_len = report_descriptor[pos + 1];
167 *key_size = 3;
168 return 1;
169 }
170 *data_len = 0; /* malformed report */
171 *key_size = 0;
172 }
173
174 /*
175 * This is a Short Item. The bottom two bits of the
176 * key contain the size code for the data section
177 * (value) for this key. Refer to the HID
178 * specification, version 1.11, section 6.2.2.2,
179 * titled "Short Items."
180 */
181 size_code = key & 0x3;
182 switch (size_code) {
183 case 0:
184 case 1:
185 case 2:
186 *data_len = size_code;
187 *key_size = 1;
188 return 1;
189 case 3:
190 *data_len = 4;
191 *key_size = 1;
192 return 1;
193 default:
194 /* Can't ever happen since size_code is & 0x3 */
195 *data_len = 0;
196 *key_size = 0;
197 break;
198 };
199
200 /* malformed report */
201 return 0;
202}
203
204/*
205 * Get bytes from a HID Report Descriptor.
206 * Only call with a num_bytes of 0, 1, 2, or 4.
207 */
208static uint32_t get_hid_report_bytes(const uint8_t *rpt, size_t len, size_t num_bytes, size_t cur)
209{
210 /* Return if there aren't enough bytes. */
211 if (cur + num_bytes >= len)
212 return 0;
213
214 if (num_bytes == 0)
215 return 0;
216 else if (num_bytes == 1)
217 return rpt[cur + 1];
218 else if (num_bytes == 2)
219 return (rpt[cur + 2] * 256 + rpt[cur + 1]);
220 else if (num_bytes == 4)
221 return (
222 rpt[cur + 4] * 0x01000000 +
223 rpt[cur + 3] * 0x00010000 +
224 rpt[cur + 2] * 0x00000100 +
225 rpt[cur + 1] * 0x00000001
226 );
227 else
228 return 0;
229}
230
231/*
232 * Iterates until the end of a Collection.
233 * Assumes that *pos is exactly at the beginning of a Collection.
234 * Skips all nested Collection, i.e. iterates until the end of current level Collection.
235 *
236 * The return value is non-0 when an end of current Collection is found,
237 * 0 when error is occurred (broken Descriptor, end of a Collection is found before its begin,
238 * or no Collection is found at all).
239 */
240static int hid_iterate_over_collection(const uint8_t *report_descriptor, uint32_t size, unsigned int *pos, int *data_len, int *key_size)
241{
242 int collection_level = 0;
243
244 while (*pos < size) {
245 int key = report_descriptor[*pos];
246 int key_cmd = key & 0xfc;
247
248 /* Determine data_len and key_size */
249 if (!get_hid_item_size(report_descriptor, size, *pos, data_len, key_size))
250 return 0; /* malformed report */
251
252 switch (key_cmd) {
253 case 0xa0: /* Collection 6.2.2.4 (Main) */
254 collection_level++;
255 break;
256 case 0xc0: /* End Collection 6.2.2.4 (Main) */
257 collection_level--;
258 break;
259 }
260
261 if (collection_level < 0) {
262 /* Broken descriptor or someone is using this function wrong,
263 * i.e. should be called exactly at the collection start */
264 return 0;
265 }
266
267 if (collection_level == 0) {
268 /* Found it!
269 * Also possible when called not at the collection start, but should not happen if used correctly */
270 return 1;
271 }
272
273 *pos += *data_len + *key_size;
274 }
275
276 return 0; /* Did not find the end of a Collection */
277}
278
279struct hid_usage_iterator {
280 unsigned int pos;
281 int usage_page_found;
282 unsigned short usage_page;
283};
284
285/*
286 * Retrieves the device's Usage Page and Usage from the report descriptor.
287 * The algorithm returns the current Usage Page/Usage pair whenever a new
288 * Collection is found and a Usage Local Item is currently in scope.
289 * Usage Local Items are consumed by each Main Item (See. 6.2.2.8).
290 * The algorithm should give similar results as Apple's:
291 * https://developer.apple.com/documentation/iokit/kiohiddeviceusagepairskey?language=objc
292 * Physical Collections are also matched (macOS does the same).
293 *
294 * This function can be called repeatedly until it returns non-0
295 * Usage is found. pos is the starting point (initially 0) and will be updated
296 * to the next search position.
297 *
298 * The return value is 0 when a pair is found.
299 * 1 when finished processing descriptor.
300 * -1 on a malformed report.
301 */
302static int get_next_hid_usage(const uint8_t *report_descriptor, uint32_t size, struct hid_usage_iterator *ctx, unsigned short *usage_page, unsigned short *usage)
303{
304 int data_len, key_size;
305 int initial = ctx->pos == 0; /* Used to handle case where no top-level application collection is defined */
306
307 int usage_found = 0;
308
309 while (ctx->pos < size) {
310 int key = report_descriptor[ctx->pos];
311 int key_cmd = key & 0xfc;
312
313 /* Determine data_len and key_size */
314 if (!get_hid_item_size(report_descriptor, size, ctx->pos, &data_len, &key_size))
315 return -1; /* malformed report */
316
317 switch (key_cmd) {
318 case 0x4: /* Usage Page 6.2.2.7 (Global) */
319 ctx->usage_page = get_hid_report_bytes(report_descriptor, size, data_len, ctx->pos);
320 ctx->usage_page_found = 1;
321 break;
322
323 case 0x8: /* Usage 6.2.2.8 (Local) */
324 if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */
325 ctx->usage_page = get_hid_report_bytes(report_descriptor, size, 2, ctx->pos + 2);
326 ctx->usage_page_found = 1;
327 *usage = get_hid_report_bytes(report_descriptor, size, 2, ctx->pos);
328 usage_found = 1;
329 }
330 else {
331 *usage = get_hid_report_bytes(report_descriptor, size, data_len, ctx->pos);
332 usage_found = 1;
333 }
334 break;
335
336 case 0xa0: /* Collection 6.2.2.4 (Main) */
337 if (!hid_iterate_over_collection(report_descriptor, size, &ctx->pos, &data_len, &key_size)) {
338 return -1;
339 }
340
341 /* A pair is valid - to be reported when Collection is found */
342 if (usage_found && ctx->usage_page_found) {
343 *usage_page = ctx->usage_page;
344 return 0;
345 }
346
347 break;
348 }
349
350 /* Skip over this key and its associated data */
351 ctx->pos += data_len + key_size;
352 }
353
354 /* If no top-level application collection is found and usage page/usage pair is found, pair is valid
355 https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections */
356 if (initial && usage_found && ctx->usage_page_found) {
357 *usage_page = ctx->usage_page;
358 return 0; /* success */
359 }
360
361 return 1; /* finished processing */
362}
363
364static struct hid_device_info *create_device_info(const struct usb_device_info *udi, const char *path, const struct usb_ctl_report_desc *ucrd)
365{
366 struct hid_device_info *root;
367 struct hid_device_info *end;
368
369 root = (struct hid_device_info *) calloc(1, sizeof(struct hid_device_info));
370 if (!root)
371 return NULL;
372
373 end = root;
374
375 /* Path */
376 end->path = (path) ? strdup(path) : NULL;
377
378 /* Vendor Id */
379 end->vendor_id = udi->udi_vendorNo;
380
381 /* Product Id */
382 end->product_id = udi->udi_productNo;
383
384 /* Serial Number */
385 end->serial_number = utf8_to_wchar_t(udi->udi_serial);
386
387 /* Release Number */
388 end->release_number = udi->udi_releaseNo;
389
390 /* Manufacturer String */
391 end->manufacturer_string = utf8_to_wchar_t(udi->udi_vendor);
392
393 /* Product String */
394 end->product_string = utf8_to_wchar_t(udi->udi_product);
395
396 /* Usage Page */
397 end->usage_page = 0;
398
399 /* Usage */
400 end->usage = 0;
401
402 /* Interface Number */
403 end->interface_number = -1;
404
405 /* Next Device Info */
406 end->next = NULL;
407
408 /* Bus Type */
409 end->bus_type = HID_API_BUS_USB;
410
411 if (ucrd) {
412 uint16_t page;
413 uint16_t usage;
414 struct hid_usage_iterator usage_iterator;
415
416 page = usage = 0;
417 memset(&usage_iterator, 0, sizeof(usage_iterator));
418
419 /*
420 * Parse the first usage and usage page
421 * out of the report descriptor.
422 */
423 if (get_next_hid_usage(ucrd->ucrd_data, ucrd->ucrd_size, &usage_iterator, &page, &usage) == 0) {
424 end->usage_page = page;
425 end->usage = usage;
426 }
427
428 /*
429 * Parse any additional usage and usage pages
430 * out of the report descriptor.
431 */
432 while (get_next_hid_usage(ucrd->ucrd_data, ucrd->ucrd_size, &usage_iterator, &page, &usage) == 0) {
433 /* Create new record for additional usage pairs */
434 struct hid_device_info *node = (struct hid_device_info *) calloc(1, sizeof(struct hid_device_info));
435
436 if (!node)
437 continue;
438
439 /* Update fields */
440 node->path = (end->path) ? strdup(end->path) : NULL;
441 node->vendor_id = end->vendor_id;
442 node->product_id = end->product_id;
443 node->serial_number = (end->serial_number) ? wcsdup(end->serial_number) : NULL;
444 node->release_number = end->release_number;
445 node->manufacturer_string = (end->manufacturer_string) ? wcsdup(end->manufacturer_string) : NULL;
446 node->product_string = (end->product_string) ? wcsdup(end->product_string) : NULL;
447 node->usage_page = page;
448 node->usage = usage;
449 node->interface_number = end->interface_number;
450 node->next = NULL;
451 node->bus_type = end->bus_type;
452
453 /* Insert node */
454 end->next = node;
455 end = node;
456 }
457 }
458
459 return root;
460}
461
462static int is_usb_controller(const char *s)
463{
464 return (!strncmp(s, "usb", 3) && isdigit((int) s[3]));
465}
466
467static int is_uhid_parent_device(const char *s)
468{
469 return (!strncmp(s, "uhidev", 6) && isdigit((int) s[6]));
470}
471
472static int is_uhid_device(const char *s)
473{
474 return (!strncmp(s, "uhid", 4) && isdigit((int) s[4]));
475}
476
477static void walk_device_tree(int drvctl, const char *dev, int depth, char arr[static HIDAPI_MAX_CHILD_DEVICES][USB_MAX_DEVNAMELEN], size_t *len, int (*cmp) (const char *))
478{
479 int res;
480 char childname[HIDAPI_MAX_CHILD_DEVICES][USB_MAX_DEVNAMELEN];
481 struct devlistargs dla;
482
483 if (depth && (!dev || !*dev))
484 return;
485
486 if (cmp(dev) && *len < HIDAPI_MAX_CHILD_DEVICES)
487 strlcpy(arr[(*len)++], dev, sizeof(*arr));
488
489 strlcpy(dla.l_devname, dev, sizeof(dla.l_devname));
490 dla.l_childname = childname;
491 dla.l_children = HIDAPI_MAX_CHILD_DEVICES;
492
493 res = ioctl(drvctl, DRVLISTDEV, &dla);
494 if (res == -1)
495 return;
496
497 /*
498 * DO NOT CHANGE THIS. This is a fail-safe check
499 * for the unlikely event that a parent device has
500 * more than HIDAPI_MAX_CHILD_DEVICES child devices
501 * to prevent iterating over uninitialized data.
502 */
503 if (dla.l_children > HIDAPI_MAX_CHILD_DEVICES)
504 return;
505
506 for (size_t i = 0; i < dla.l_children; i++)
507 walk_device_tree(drvctl, dla.l_childname[i], depth + 1, arr, len, cmp);
508}
509
510static void enumerate_usb_devices(int bus, uint8_t addr, enumerate_devices_callback func, void *data)
511{
512 int res;
513 struct usb_device_info udi;
514
515 udi.udi_addr = addr;
516
517 res = ioctl(bus, USB_DEVICEINFO, &udi);
518 if (res == -1)
519 return;
520
521 for (int port = 0; port < udi.udi_nports; port++) {
522 addr = udi.udi_ports[port];
523 if (addr >= USB_MAX_DEVICES)
524 continue;
525
526 enumerate_usb_devices(bus, addr, func, data);
527 }
528
529 func(&udi, data);
530}
531
532static void hid_enumerate_callback(const struct usb_device_info *udi, void *data)
533{
534 struct hid_enumerate_data *hed;
535
536 hed = (struct hid_enumerate_data *) data;
537
538 if (hed->vendor_id != 0 && hed->vendor_id != udi->udi_vendorNo)
539 return;
540
541 if (hed->product_id != 0 && hed->product_id != udi->udi_productNo)
542 return;
543
544 for (size_t i = 0; i < USB_MAX_DEVNAMES; i++) {
545 const char *parent_dev;
546 char arr[HIDAPI_MAX_CHILD_DEVICES][USB_MAX_DEVNAMELEN];
547 size_t len;
548 const char *child_dev;
549 char devpath[USB_MAX_DEVNAMELEN];
550 int uhid;
551 struct usb_ctl_report_desc ucrd;
552 int use_ucrd;
553 struct hid_device_info *node;
554
555 parent_dev = udi->udi_devnames[i];
556 if (!is_uhid_parent_device(parent_dev))
557 continue;
558
559 len = 0;
560 walk_device_tree(hed->drvctl, parent_dev, 0, arr, &len, is_uhid_device);
561
562 if (len == 0)
563 continue;
564
565 child_dev = arr[0];
566 strlcpy(devpath, "/dev/", sizeof(devpath));
567 strlcat(devpath, child_dev, sizeof(devpath));
568
569 uhid = open(devpath, O_RDONLY | O_CLOEXEC);
570 if (uhid >= 0) {
571 use_ucrd = (ioctl(uhid, USB_GET_REPORT_DESC, &ucrd) != -1);
572 close(uhid);
573 } else {
574 use_ucrd = 0;
575 }
576
577 node = create_device_info(udi, parent_dev, (use_ucrd) ? &ucrd : NULL);
578 if (!node)
579 continue;
580
581 if (!hed->root) {
582 hed->root = node;
583 hed->end = node;
584 } else {
585 hed->end->next = node;
586 hed->end = node;
587 }
588
589 while (hed->end->next)
590 hed->end = hed->end->next;
591 }
592}
593
594static int set_report(hid_device *dev, const uint8_t *data, size_t length, int report)
595{
596 int res;
597 int device_handle;
598 struct usb_ctl_report ucr;
599
600 if (length < 1) {
601 register_device_error(dev, "report must be greater than 1 byte");
602 return -1;
603 }
604
605 device_handle = dev->report_handles[*data];
606 if (device_handle < 0) {
607 register_device_error_format(dev, "unsupported report id: %hhu", *data);
608 return -1;
609 }
610
611 length--;
612 data++;
613
614 if (length > sizeof(ucr.ucr_data)) {
615 register_device_error_format(dev, "report must be less than or equal to %zu bytes", sizeof(ucr.ucr_data));
616 return -1;
617 }
618
619 ucr.ucr_report = report;
620 memcpy(ucr.ucr_data, data, length);
621
622 res = ioctl(device_handle, USB_SET_REPORT, &ucr);
623 if (res == -1) {
624 register_device_error_format(dev, "ioctl (USB_SET_REPORT): %s", strerror(errno));
625 return -1;
626 }
627
628 return (int) (length + 1);
629}
630
631static int get_report(hid_device *dev, uint8_t *data, size_t length, int report)
632{
633 int res;
634 int device_handle;
635 struct usb_ctl_report ucr;
636
637 if (length < 1) {
638 register_device_error(dev, "report must be greater than 1 byte");
639 return -1;
640 }
641
642 device_handle = dev->report_handles[*data];
643 if (device_handle < 0) {
644 register_device_error_format(dev, "unsupported report id: %hhu", *data);
645 return -1;
646 }
647
648 length--;
649 data++;
650
651 if (length > sizeof(ucr.ucr_data)) {
652 length = sizeof(ucr.ucr_data);
653 }
654
655 ucr.ucr_report = report;
656
657 res = ioctl(device_handle, USB_GET_REPORT, &ucr);
658 if (res == -1) {
659 register_device_error_format(dev, "ioctl (USB_GET_REPORT): %s", strerror(errno));
660 return -1;
661 }
662
663 memcpy(data, ucr.ucr_data, length);
664
665 return (int) (length + 1);
666}
667
668int HID_API_EXPORT HID_API_CALL hid_init(void)
669{
670 /* indicate no error */
671 register_global_error(NULL);
672
673 return 0;
674}
675
676int HID_API_EXPORT HID_API_CALL hid_exit(void)
677{
678 /* Free global error message */
679 register_global_error(NULL);
680
681 return 0;
682}
683
684struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
685{
686 int res;
687 int drvctl;
688 char arr[HIDAPI_MAX_CHILD_DEVICES][USB_MAX_DEVNAMELEN];
689 size_t len;
690 struct hid_enumerate_data hed;
691
692 res = hid_init();
693 if (res == -1)
694 return NULL;
695
696 drvctl = open(DRVCTLDEV, O_RDONLY | O_CLOEXEC);
697 if (drvctl == -1) {
698 register_global_error_format("failed to open drvctl: %s", strerror(errno));
699 return NULL;
700 }
701
702 len = 0;
703 walk_device_tree(drvctl, "", 0, arr, &len, is_usb_controller);
704
705 hed.root = NULL;
706 hed.end = NULL;
707 hed.drvctl = drvctl;
708 hed.vendor_id = vendor_id;
709 hed.product_id = product_id;
710
711 for (size_t i = 0; i < len; i++) {
712 char devpath[USB_MAX_DEVNAMELEN];
713 int bus;
714
715 strlcpy(devpath, "/dev/", sizeof(devpath));
716 strlcat(devpath, arr[i], sizeof(devpath));
717
718 bus = open(devpath, O_RDONLY | O_CLOEXEC);
719 if (bus == -1)
720 continue;
721
722 enumerate_usb_devices(bus, 0, hid_enumerate_callback, &hed);
723
724 close(bus);
725 }
726
727 close(drvctl);
728
729 return hed.root;
730}
731
732void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
733{
734 while (devs) {
735 struct hid_device_info *next = devs->next;
736 free(devs->path);
737 free(devs->serial_number);
738 free(devs->manufacturer_string);
739 free(devs->product_string);
740 free(devs);
741 devs = next;
742 }
743}
744
745HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
746{
747 struct hid_device_info *devs;
748 struct hid_device_info *dev;
749 char path[USB_MAX_DEVNAMELEN];
750
751 devs = hid_enumerate(vendor_id, product_id);
752 if (!devs)
753 return NULL;
754
755 *path = '\0';
756
757 for (dev = devs; dev; dev = dev->next) {
758 if (dev->vendor_id != vendor_id)
759 continue;
760
761 if (dev->product_id != product_id)
762 continue;
763
764 if (serial_number && wcscmp(dev->serial_number, serial_number))
765 continue;
766
767 strlcpy(path, dev->path, sizeof(path));
768
769 break;
770 }
771
772 hid_free_enumeration(devs);
773
774 if (*path == '\0') {
775 register_global_error("Device with requested VID/PID/(SerialNumber) not found");
776 return NULL;
777 }
778
779 return hid_open_path(path);
780}
781
782HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
783{
784 int res;
785 hid_device *dev;
786 int drvctl;
787 char arr[HIDAPI_MAX_CHILD_DEVICES][USB_MAX_DEVNAMELEN];
788 size_t len;
789
790 res = hid_init();
791 if (res == -1)
792 goto err_0;
793
794 dev = (hid_device *) calloc(1, sizeof(hid_device));
795 if (!dev) {
796 register_global_error("could not allocate hid_device");
797 goto err_0;
798 }
799
800 drvctl = open(DRVCTLDEV, O_RDONLY | O_CLOEXEC);
801 if (drvctl == -1) {
802 register_global_error_format("failed to open drvctl: %s", strerror(errno));
803 goto err_1;
804 }
805
806 if (!is_uhid_parent_device(path)) {
807 register_global_error("not a uhidev device");
808 goto err_2;
809 }
810
811 len = 0;
812 walk_device_tree(drvctl, path, 0, arr, &len, is_uhid_device);
813
814 dev->poll_handles_length = 0;
815 memset(dev->poll_handles, 0x00, sizeof(dev->poll_handles));
816 memset(dev->report_handles, 0xff, sizeof(dev->report_handles));
817
818 for (size_t i = 0; i < len; i++) {
819 const char *child_dev;
820 char devpath[USB_MAX_DEVNAMELEN];
821 int uhid;
822 int rep_id;
823 struct pollfd *ph;
824
825 child_dev = arr[i];
826 strlcpy(devpath, "/dev/", sizeof(devpath));
827 strlcat(devpath, child_dev, sizeof(devpath));
828
829 uhid = open(devpath, O_RDWR | O_CLOEXEC);
830 if (uhid == -1) {
831 register_global_error_format("failed to open %s: %s", child_dev, strerror(errno));
832 goto err_3;
833 }
834
835 res = ioctl(uhid, USB_GET_REPORT_ID, &rep_id);
836 if (res == -1) {
837 close(uhid);
838 register_global_error_format("failed to get report id %s: %s", child_dev, strerror(errno));
839 goto err_3;
840 }
841
842 ph = &dev->poll_handles[dev->poll_handles_length++];
843 ph->fd = uhid;
844 ph->events = POLLIN;
845 ph->revents = 0;
846 dev->report_handles[rep_id] = uhid;
847 dev->device_handle = uhid;
848 }
849
850 dev->blocking = 1;
851 dev->last_error_str = NULL;
852 dev->device_info = NULL;
853 strlcpy(dev->path, path, sizeof(dev->path));
854
855 register_global_error(NULL);
856 return dev;
857
858err_3:
859 for (size_t i = 0; i < dev->poll_handles_length; i++)
860 close(dev->poll_handles[i].fd);
861err_2:
862 close(drvctl);
863err_1:
864 free(dev);
865err_0:
866 return NULL;
867}
868
869int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
870{
871 return set_report(dev, data, length, UHID_OUTPUT_REPORT);
872}
873
874int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
875{
876 int res;
877 size_t i;
878 struct pollfd *ph;
879 ssize_t n;
880
881 res = poll(dev->poll_handles, dev->poll_handles_length, milliseconds);
882 if (res == -1) {
883 register_device_error_format(dev, "error while polling: %s", strerror(errno));
884 return -1;
885 }
886
887 if (res == 0)
888 return 0;
889
890 for (i = 0; i < dev->poll_handles_length; i++) {
891 ph = &dev->poll_handles[i];
892
893 if (ph->revents & (POLLERR | POLLHUP | POLLNVAL)) {
894 register_device_error(dev, "device IO error while polling");
895 return -1;
896 }
897
898 if (ph->revents & POLLIN)
899 break;
900 }
901
902 if (i == dev->poll_handles_length)
903 return 0;
904
905 n = read(ph->fd, data, length);
906 if (n == -1) {
907 if (errno == EAGAIN || errno == EINPROGRESS)
908 n = 0;
909 else
910 register_device_error_format(dev, "error while reading: %s", strerror(errno));
911 }
912
913 return n;
914}
915
916int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
917{
918 return hid_read_timeout(dev, data, length, (dev->blocking) ? -1 : 0);
919}
920
921int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
922{
923 dev->blocking = !nonblock;
924 return 0;
925}
926
927int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
928{
929 return set_report(dev, data, length, UHID_FEATURE_REPORT);
930}
931
932int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
933{
934 return get_report(dev, data, length, UHID_FEATURE_REPORT);
935}
936
937int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
938{
939 return get_report(dev, data, length, UHID_INPUT_REPORT);
940}
941
942void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
943{
944 if (!dev)
945 return;
946
947 /* Free the device error message */
948 register_device_error(dev, NULL);
949
950 hid_free_enumeration(dev->device_info);
951
952 for (size_t i = 0; i < dev->poll_handles_length; i++)
953 close(dev->poll_handles[i].fd);
954
955 free(dev);
956}
957
958int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
959{
960 struct hid_device_info *hdi;
961
962 if (!string || !maxlen) {
963 register_device_error(dev, "Zero buffer/length");
964 return -1;
965 }
966
967 hdi = hid_get_device_info(dev);
968 if (!dev)
969 return -1;
970
971 if (hdi->manufacturer_string) {
972 wcsncpy(string, hdi->manufacturer_string, maxlen);
973 string[maxlen - 1] = L'\0';
974 } else {
975 string[0] = L'\0';
976 }
977
978 return 0;
979}
980
981int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
982{
983 struct hid_device_info *hdi;
984
985 if (!string || !maxlen) {
986 register_device_error(dev, "Zero buffer/length");
987 return -1;
988 }
989
990 hdi = hid_get_device_info(dev);
991 if (!dev)
992 return -1;
993
994 if (hdi->product_string) {
995 wcsncpy(string, hdi->product_string, maxlen);
996 string[maxlen - 1] = L'\0';
997 } else {
998 string[0] = L'\0';
999 }
1000
1001 return 0;
1002}
1003
1004int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1005{
1006 struct hid_device_info *hdi;
1007
1008 if (!string || !maxlen) {
1009 register_device_error(dev, "Zero buffer/length");
1010 return -1;
1011 }
1012
1013 hdi = hid_get_device_info(dev);
1014 if (!dev)
1015 return -1;
1016
1017 if (hdi->serial_number) {
1018 wcsncpy(string, hdi->serial_number, maxlen);
1019 string[maxlen - 1] = L'\0';
1020 } else {
1021 string[0] = L'\0';
1022 }
1023
1024 return 0;
1025}
1026
1027struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_get_device_info(hid_device *dev)
1028{
1029 int res;
1030 struct usb_device_info udi;
1031 struct usb_ctl_report_desc ucrd;
1032 int use_ucrd;
1033 struct hid_device_info *hdi;
1034
1035 if (dev->device_info)
1036 return dev->device_info;
1037
1038 res = ioctl(dev->device_handle, USB_GET_DEVICEINFO, &udi);
1039 if (res == -1) {
1040 register_device_error_format(dev, "ioctl (USB_GET_DEVICEINFO): %s", strerror(errno));
1041 return NULL;
1042 }
1043
1044 use_ucrd = (ioctl(dev->device_handle, USB_GET_REPORT_DESC, &ucrd) != -1);
1045
1046 hdi = create_device_info(&udi, dev->path, (use_ucrd) ? &ucrd : NULL);
1047 if (!hdi) {
1048 register_device_error(dev, "failed to create device info");
1049 return NULL;
1050 }
1051
1052 dev->device_info = hdi;
1053
1054 return hdi;
1055}
1056
1057int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1058{
1059 int res;
1060 struct usb_string_desc usd;
1061 usb_string_descriptor_t *str;
1062 iconv_t ic;
1063 char *src;
1064 size_t srcleft;
1065 char *dst;
1066 size_t dstleft;
1067 size_t ic_res;
1068
1069 /* First let us get the supported language IDs. */
1070 usd.usd_string_index = 0;
1071 usd.usd_language_id = 0;
1072
1073 res = ioctl(dev->device_handle, USB_GET_STRING_DESC, &usd);
1074 if (res == -1) {
1075 register_device_error_format(dev, "ioctl (USB_GET_STRING_DESC): %s", strerror(errno));
1076 return -1;
1077 }
1078
1079 str = &usd.usd_desc;
1080
1081 if (str->bLength < 4) {
1082 register_device_error(dev, "failed to get supported language IDs");
1083 return -1;
1084 }
1085
1086 /* Now we can get the requested string. */
1087 usd.usd_string_index = string_index;
1088 usd.usd_language_id = UGETW(str->bString[0]);
1089
1090 res = ioctl(dev->device_handle, USB_GET_STRING_DESC, &usd);
1091 if (res == -1) {
1092 register_device_error_format(dev, "ioctl (USB_GET_STRING_DESC): %s", strerror(errno));
1093 return -1;
1094 }
1095
1096 /* Now we need to convert it, using iconv. */
1097#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1098 ic = iconv_open("utf-32le", "utf-16le");
1099#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1100 ic = iconv_open("utf-32be", "utf-16le");
1101#endif
1102 if (ic == (iconv_t) -1) {
1103 register_device_error_format(dev, "iconv_open failed: %s", strerror(errno));
1104 return -1;
1105 }
1106
1107 src = (char *) str->bString;
1108 srcleft = str->bLength - 2;
1109 dst = (char *) string;
1110 dstleft = sizeof(wchar_t[maxlen]);
1111
1112 ic_res = iconv(ic, &src, &srcleft, &dst, &dstleft);
1113 iconv_close(ic);
1114 if (ic_res == (size_t) -1) {
1115 register_device_error_format(dev, "iconv failed: %s", strerror(errno));
1116 return -1;
1117 }
1118
1119 /* Write the terminating NULL. */
1120 string[maxlen - 1] = L'\0';
1121 if (dstleft >= sizeof(wchar_t))
1122 *((wchar_t *) dst) = L'\0';
1123
1124 return 0;
1125}
1126
1127int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
1128{
1129 int res;
1130 struct usb_ctl_report_desc ucrd;
1131
1132 res = ioctl(dev->device_handle, USB_GET_REPORT_DESC, &ucrd);
1133 if (res == -1) {
1134 register_device_error_format(dev, "ioctl (USB_GET_REPORT_DESC): %s", strerror(errno));
1135 return -1;
1136 }
1137
1138 if ((size_t) ucrd.ucrd_size < buf_size)
1139 buf_size = (size_t) ucrd.ucrd_size;
1140
1141 memcpy(buf, ucrd.ucrd_data, buf_size);
1142
1143 return (int) buf_size;
1144}
1145
1146HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev)
1147{
1148 if (dev) {
1149 if (dev->last_error_str == NULL)
1150 return L"Success";
1151 return dev->last_error_str;
1152 }
1153
1154 if (last_global_error_str == NULL)
1155 return L"Success";
1156 return last_global_error_str;
1157}
1158
1159HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void)
1160{
1161 static const struct hid_api_version api_version = {
1162 .major = HID_API_VERSION_MAJOR,
1163 .minor = HID_API_VERSION_MINOR,
1164 .patch = HID_API_VERSION_PATCH
1165 };
1166
1167 return &api_version;
1168}
1169
1170HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
1171{
1172 return HID_API_VERSION_STR;
1173}
diff --git a/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-hidraw.pc.in b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-hidraw.pc.in
new file mode 100644
index 0000000..28b9fe6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-hidraw.pc.in
@@ -0,0 +1,11 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: hidapi-hidraw
7Description: C Library for USB/Bluetooth HID device access from Linux, Mac OS X, FreeBSD, and Windows. This is the hidraw implementation.
8URL: https://github.com/libusb/hidapi
9Version: @VERSION@
10Libs: -L${libdir} -lhidapi-hidraw
11Cflags: -I${includedir}/hidapi
diff --git a/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-libusb.pc.in b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-libusb.pc.in
new file mode 100644
index 0000000..d51e98f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-libusb.pc.in
@@ -0,0 +1,11 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: hidapi-libusb
7Description: C Library for USB HID device access from Linux, Mac OS X, FreeBSD, and Windows. This is the libusb implementation.
8URL: https://github.com/libusb/hidapi
9Version: @VERSION@
10Libs: -L${libdir} -lhidapi-libusb
11Cflags: -I${includedir}/hidapi
diff --git a/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-netbsd.pc.in b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-netbsd.pc.in
new file mode 100644
index 0000000..fcb5ca2
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi-netbsd.pc.in
@@ -0,0 +1,11 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: hidapi-netbsd
7Description: C Library for USB/Bluetooth HID device access from Linux, Mac OS X, FreeBSD, and Windows. This is the netbsd implementation.
8URL: https://github.com/libusb/hidapi
9Version: @VERSION@
10Libs: -L${libdir} -lhidapi-netbsd
11Cflags: -I${includedir}/hidapi
diff --git a/contrib/SDL-3.2.8/src/hidapi/pc/hidapi.pc.in b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi.pc.in
new file mode 100644
index 0000000..75b11a5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/pc/hidapi.pc.in
@@ -0,0 +1,11 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: hidapi
7Description: C Library for USB/Bluetooth HID device access from Linux, Mac OS X, FreeBSD, and Windows.
8URL: https://github.com/libusb/hidapi
9Version: @VERSION@
10Libs: -L${libdir} -lhidapi
11Cflags: -I${includedir}/hidapi
diff --git a/contrib/SDL-3.2.8/src/hidapi/src/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/src/CMakeLists.txt
new file mode 100644
index 0000000..e663c3f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/src/CMakeLists.txt
@@ -0,0 +1,206 @@
1get_filename_component(PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
2
3# Read version from file
4file(READ "${PROJECT_ROOT}/VERSION" RAW_VERSION_STR)
5string(REGEX MATCH "^([0-9]+\\.[0-9]+\\.[0-9]+)(.*)" VERSION_STR "${RAW_VERSION_STR}")
6
7if(NOT VERSION_STR)
8 message(FATAL_ERROR "Broken VERSION file, couldn't parse '${PROJECT_ROOT}/VERSION' with content: '${RAW_VERSION_STR}'")
9endif()
10
11set(VERSION "${CMAKE_MATCH_1}")
12string(STRIP "${CMAKE_MATCH_2}" VERSION_SUFFIX)
13# compatibility with find_package() vs add_subdirectory
14set(hidapi_VERSION "${VERSION}" PARENT_SCOPE)
15#
16
17if(DEFINED HIDAPI_PRINT_VERSION AND HIDAPI_PRINT_VERSION)
18 set(HIDAPI_PRINT_VERSION "hidapi: v${VERSION}")
19 if(VERSION_SUFFIX)
20 set(HIDAPI_PRINT_VERSION "${HIDAPI_PRINT_VERSION} (${VERSION_SUFFIX})")
21 endif()
22 message(STATUS "${HIDAPI_PRINT_VERSION}")
23endif()
24
25project(hidapi VERSION "${VERSION}" LANGUAGES C)
26
27# Defaults and required options
28
29if(NOT DEFINED HIDAPI_WITH_TESTS)
30 set(HIDAPI_WITH_TESTS OFF)
31endif()
32if(NOT DEFINED BUILD_SHARED_LIBS)
33 set(BUILD_SHARED_LIBS ON)
34endif()
35if(NOT DEFINED HIDAPI_INSTALL_TARGETS)
36 set(HIDAPI_INSTALL_TARGETS OFF)
37endif()
38if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
39 set(CMAKE_POSITION_INDEPENDENT_CODE ON)
40endif()
41
42get_directory_property(IS_EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL)
43if(IS_EXCLUDE_FROM_ALL)
44 if(HIDAPI_INSTALL_TARGETS)
45 message(WARNING "Installing EXCLUDE_FROM_ALL targets in an undefined behavior in CMake.\nDon't add 'hidapi' sundirectory with 'EXCLUDE_FROM_ALL' property, or don't set 'HIDAPI_INSTALL_TARGETS' to TRUE.")
46 endif()
47endif()
48
49# Helper(s)
50
51function(hidapi_configure_pc PC_IN_FILE)
52 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pc")
53
54 set(VERSION "${VERSION}${VERSION_SUFFIX}")
55 set(prefix "${CMAKE_INSTALL_PREFIX}")
56 set(exec_prefix "\${prefix}")
57 if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
58 set(libdir "${CMAKE_INSTALL_LIBDIR}")
59 else()
60 set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
61 endif()
62 if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
63 set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
64 else()
65 set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
66 endif()
67
68 get_filename_component(PC_IN_FILENAME "${PC_IN_FILE}" NAME_WE)
69 set(PC_FILE "${CMAKE_CURRENT_BINARY_DIR}/pc/${PC_IN_FILENAME}.pc")
70 configure_file("${PC_IN_FILE}" "${PC_FILE}" @ONLY)
71 if(HIDAPI_INSTALL_TARGETS)
72 install(FILES "${PC_FILE}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
73 endif()
74endfunction()
75
76# The library
77
78if(HIDAPI_INSTALL_TARGETS)
79 include(GNUInstallDirs)
80endif()
81
82add_library(hidapi_include INTERFACE)
83target_include_directories(hidapi_include INTERFACE
84 "$<BUILD_INTERFACE:${PROJECT_ROOT}/hidapi>"
85)
86if(APPLE AND CMAKE_FRAMEWORK)
87 # FIXME: https://github.com/libusb/hidapi/issues/492: it is untrivial to set the include path for Framework correctly
88else()
89 target_include_directories(hidapi_include INTERFACE
90 "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/hidapi>"
91 )
92endif()
93set_target_properties(hidapi_include PROPERTIES EXPORT_NAME "include")
94set(HIDAPI_PUBLIC_HEADERS "${PROJECT_ROOT}/hidapi/hidapi.h")
95
96add_library(hidapi::include ALIAS hidapi_include)
97
98if(HIDAPI_INSTALL_TARGETS)
99 install(TARGETS hidapi_include EXPORT hidapi)
100endif()
101
102set(EXPORT_ALIAS)
103set(EXPORT_COMPONENTS)
104
105set(HIDAPI_NEED_EXPORT_THREADS FALSE)
106set(HIDAPI_NEED_EXPORT_LIBUSB FALSE)
107set(HIDAPI_NEED_EXPORT_LIBUDEV FALSE)
108set(HIDAPI_NEED_EXPORT_ICONV FALSE)
109
110if(WIN32)
111 target_include_directories(hidapi_include INTERFACE
112 "$<BUILD_INTERFACE:${PROJECT_ROOT}/windows>"
113 )
114 add_subdirectory("${PROJECT_ROOT}/windows" windows)
115 set(EXPORT_ALIAS winapi)
116 list(APPEND EXPORT_COMPONENTS winapi)
117elseif(APPLE)
118 target_include_directories(hidapi_include INTERFACE
119 "$<BUILD_INTERFACE:${PROJECT_ROOT}/mac>"
120 )
121 add_subdirectory("${PROJECT_ROOT}/mac" mac)
122 set(EXPORT_ALIAS darwin)
123 list(APPEND EXPORT_COMPONENTS darwin)
124 if(NOT BUILD_SHARED_LIBS)
125 set(HIDAPI_NEED_EXPORT_THREADS TRUE)
126 endif()
127else()
128 if(NOT DEFINED HIDAPI_WITH_LIBUSB)
129 set(HIDAPI_WITH_LIBUSB ON)
130 endif()
131 if(CMAKE_SYSTEM_NAME MATCHES "Linux")
132 if(NOT DEFINED HIDAPI_WITH_HIDRAW)
133 set(HIDAPI_WITH_HIDRAW ON)
134 endif()
135 if(HIDAPI_WITH_HIDRAW)
136 add_subdirectory("${PROJECT_ROOT}/linux" linux)
137 list(APPEND EXPORT_COMPONENTS hidraw)
138 set(EXPORT_ALIAS hidraw)
139 if(NOT BUILD_SHARED_LIBS)
140 set(HIDAPI_NEED_EXPORT_THREADS TRUE)
141 set(HIDAPI_NEED_EXPORT_LIBUDEV TRUE)
142 endif()
143 endif()
144 elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
145 if(NOT DEFINED HIDAPI_WITH_NETBSD)
146 set(HIDAPI_WITH_NETBSD ON)
147 endif()
148 if(HIDAPI_WITH_NETBSD)
149 add_subdirectory("${PROJECT_ROOT}/netbsd" netbsd)
150 list(APPEND EXPORT_COMPONENTS netbsd)
151 set(EXPORT_ALIAS netbsd)
152 if(NOT BUILD_SHARED_LIBS)
153 set(HIDAPI_NEED_EXPORT_THREADS TRUE)
154 endif()
155 endif()
156 else()
157 set(HIDAPI_WITH_LIBUSB ON)
158 endif()
159 if(HIDAPI_WITH_LIBUSB)
160 target_include_directories(hidapi_include INTERFACE
161 "$<BUILD_INTERFACE:${PROJECT_ROOT}/libusb>"
162 )
163 if(NOT DEFINED HIDAPI_NO_ICONV)
164 set(HIDAPI_NO_ICONV OFF)
165 endif()
166 add_subdirectory("${PROJECT_ROOT}/libusb" libusb)
167 list(APPEND EXPORT_COMPONENTS libusb)
168 if(NOT EXPORT_ALIAS)
169 set(EXPORT_ALIAS libusb)
170 endif()
171 if(NOT BUILD_SHARED_LIBS)
172 set(HIDAPI_NEED_EXPORT_THREADS TRUE)
173 if(NOT TARGET usb-1.0)
174 set(HIDAPI_NEED_EXPORT_LIBUSB TRUE)
175 endif()
176 endif()
177 elseif(NOT TARGET hidapi_hidraw)
178 message(FATAL_ERROR "Select at least one option to build: HIDAPI_WITH_LIBUSB or HIDAPI_WITH_HIDRAW")
179 endif()
180endif()
181
182add_library(hidapi::hidapi ALIAS hidapi_${EXPORT_ALIAS})
183
184if(HIDAPI_INSTALL_TARGETS)
185 include(CMakePackageConfigHelpers)
186 set(EXPORT_DENERATED_LOCATION "${CMAKE_BINARY_DIR}/export_generated")
187 set(EXPORT_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/hidapi")
188 write_basic_package_version_file("${EXPORT_DENERATED_LOCATION}/hidapi-config-version.cmake"
189 COMPATIBILITY SameMajorVersion
190 )
191 configure_package_config_file("cmake/hidapi-config.cmake.in" "${EXPORT_DENERATED_LOCATION}/hidapi-config.cmake"
192 INSTALL_DESTINATION "${EXPORT_DESTINATION}"
193 NO_SET_AND_CHECK_MACRO
194 )
195
196 install(EXPORT hidapi
197 DESTINATION "${EXPORT_DESTINATION}"
198 NAMESPACE hidapi::
199 FILE "libhidapi.cmake"
200 )
201 install(FILES
202 "${EXPORT_DENERATED_LOCATION}/hidapi-config-version.cmake"
203 "${EXPORT_DENERATED_LOCATION}/hidapi-config.cmake"
204 DESTINATION "${EXPORT_DESTINATION}"
205 )
206endif()
diff --git a/contrib/SDL-3.2.8/src/hidapi/src/cmake/hidapi-config.cmake.in b/contrib/SDL-3.2.8/src/hidapi/src/cmake/hidapi-config.cmake.in
new file mode 100644
index 0000000..4226c8c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/src/cmake/hidapi-config.cmake.in
@@ -0,0 +1,61 @@
1@PACKAGE_INIT@
2
3set(hidapi_VERSION_MAJOR "@hidapi_VERSION_MAJOR@")
4set(hidapi_VERSION_MINOR "@hidapi_VERSION_MINOR@")
5set(hidapi_VERSION_PATCH "@hidapi_VERSION_PATCH@")
6set(hidapi_VERSION "@hidapi_VERSION@")
7set(hidapi_VERSION_STR "@hidapi_VERSION@@VERSION_SUFFIX@")
8
9set(hidapi_FOUND FALSE)
10
11set(HIDAPI_NEED_EXPORT_THREADS @HIDAPI_NEED_EXPORT_THREADS@)
12set(HIDAPI_NEED_EXPORT_LIBUSB @HIDAPI_NEED_EXPORT_LIBUSB@)
13set(HIDAPI_NEED_EXPORT_LIBUDEV @HIDAPI_NEED_EXPORT_LIBUDEV@)
14set(HIDAPI_NEED_EXPORT_ICONV @HIDAPI_NEED_EXPORT_ICONV@)
15
16if(HIDAPI_NEED_EXPORT_THREADS)
17 if(CMAKE_VERSION VERSION_LESS 3.4.3)
18 message(FATAL_ERROR "This file relies on consumers using CMake 3.4.3 or greater.")
19 endif()
20 find_package(Threads REQUIRED)
21endif()
22
23if(HIDAPI_NEED_EXPORT_LIBUSB OR HIDAPI_NEED_EXPORT_LIBUDEV)
24 if(CMAKE_VERSION VERSION_LESS 3.6.3)
25 message(FATAL_ERROR "This file relies on consumers using CMake 3.6.3 or greater.")
26 endif()
27 find_package(PkgConfig)
28 if(HIDAPI_NEED_EXPORT_LIBUSB)
29 pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0>=1.0.9)
30 endif()
31 if(HIDAPI_NEED_EXPORT_LIBUDEV)
32 pkg_check_modules(libudev REQUIRED IMPORTED_TARGET libudev)
33 endif()
34endif()
35
36if(HIDAPI_NEED_EXPORT_ICONV)
37 if(CMAKE_VERSION VERSION_LESS 3.11)
38 message(WARNING "HIDAPI requires CMake target Iconv::Iconv, make sure to provide it")
39 else()
40 find_package(Iconv REQUIRED)
41 endif()
42endif()
43
44include("${CMAKE_CURRENT_LIST_DIR}/libhidapi.cmake")
45
46set(hidapi_FOUND TRUE)
47
48foreach(_component @EXPORT_COMPONENTS@)
49 if(TARGET hidapi::${_component})
50 set(hidapi_${_component}_FOUND TRUE)
51 endif()
52endforeach()
53
54check_required_components(hidapi)
55
56if(NOT TARGET hidapi::hidapi)
57 add_library(hidapi::hidapi INTERFACE IMPORTED)
58 set_target_properties(hidapi::hidapi PROPERTIES
59 INTERFACE_LINK_LIBRARIES hidapi::@EXPORT_ALIAS@
60 )
61endif()
diff --git a/contrib/SDL-3.2.8/src/hidapi/subprojects/README.md b/contrib/SDL-3.2.8/src/hidapi/subprojects/README.md
new file mode 100644
index 0000000..8ba8f60
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/subprojects/README.md
@@ -0,0 +1,2 @@
1This folder is used only to support [meson.build](../meson.build) `subproject` command
2which would only look for a subproject in a "subprojects" directory. \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/subprojects/hidapi_build_cmake/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/subprojects/hidapi_build_cmake/CMakeLists.txt
new file mode 100644
index 0000000..4586ce6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/subprojects/hidapi_build_cmake/CMakeLists.txt
@@ -0,0 +1,10 @@
1cmake_minimum_required(VERSION 3.1.3...3.25 FATAL_ERROR)
2project(hidapi LANGUAGES C)
3
4file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/root")
5
6foreach(ROOT_ELEMENT CMakeLists.txt hidapi src windows linux mac libusb pc VERSION)
7 file(COPY "${CMAKE_CURRENT_LIST_DIR}/../../${ROOT_ELEMENT}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/root/")
8endforeach()
9
10add_subdirectory("${CMAKE_CURRENT_BINARY_DIR}/root" hidapi_root)
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile-manual b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile-manual
new file mode 100644
index 0000000..3f61705
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile-manual
@@ -0,0 +1,26 @@
1
2
3OS=$(shell uname)
4
5ifeq ($(OS), Darwin)
6 FILE=Makefile.mac
7endif
8
9ifneq (,$(findstring MINGW,$(OS)))
10 FILE=Makefile.mingw
11endif
12
13ifeq ($(OS), Linux)
14 FILE=Makefile.linux
15endif
16
17ifeq ($(OS), FreeBSD)
18 FILE=Makefile.freebsd
19endif
20
21ifeq ($(FILE), )
22all:
23 $(error Your platform ${OS} is not supported at this time.)
24endif
25
26include $(FILE)
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.am b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.am
new file mode 100644
index 0000000..1c02f3f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.am
@@ -0,0 +1,43 @@
1
2AM_CPPFLAGS = -I$(top_srcdir)/hidapi/ $(CFLAGS_TESTGUI)
3
4if OS_LINUX
5## Linux
6bin_PROGRAMS = hidapi-hidraw-testgui hidapi-libusb-testgui
7
8hidapi_hidraw_testgui_SOURCES = test.cpp
9hidapi_hidraw_testgui_LDADD = $(top_builddir)/linux/libhidapi-hidraw.la $(LIBS_TESTGUI)
10
11hidapi_libusb_testgui_SOURCES = test.cpp
12hidapi_libusb_testgui_LDADD = $(top_builddir)/libusb/libhidapi-libusb.la $(LIBS_TESTGUI)
13else
14## Other OS's
15bin_PROGRAMS = hidapi-testgui
16
17hidapi_testgui_SOURCES = test.cpp
18hidapi_testgui_LDADD = $(top_builddir)/$(backend)/libhidapi.la $(LIBS_TESTGUI)
19endif
20
21if OS_DARWIN
22hidapi_testgui_SOURCES = test.cpp mac_support_cocoa.m mac_support.h
23# Rules for copying the binary and its dependencies into the app bundle.
24TestGUI.app/Contents/MacOS/hidapi-testgui$(EXEEXT): hidapi-testgui$(EXEEXT)
25 $(srcdir)/copy_to_bundle.sh
26
27all: all-am TestGUI.app/Contents/MacOS/hidapi-testgui$(EXEEXT)
28
29endif
30
31EXTRA_DIST = \
32 copy_to_bundle.sh \
33 Makefile-manual \
34 Makefile.freebsd \
35 Makefile.linux \
36 Makefile.mac \
37 Makefile.mingw \
38 TestGUI.app.in \
39 testgui.sln \
40 testgui.vcproj
41
42distclean-local:
43 rm -rf TestGUI.app
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.freebsd b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.freebsd
new file mode 100644
index 0000000..09a2473
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.freebsd
@@ -0,0 +1,33 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: testgui
10
11CC=cc
12CXX=c++
13COBJS=../libusb/hid.o
14CPPOBJS=test.o
15OBJS=$(COBJS) $(CPPOBJS)
16CFLAGS=-I../hidapi -I/usr/local/include `fox-config --cflags` -Wall -g -c
17LDFLAGS= -L/usr/local/lib
18LIBS= -lusb -liconv `fox-config --libs` -pthread
19
20
21testgui: $(OBJS)
22 $(CXX) -Wall -g $^ $(LDFLAGS) -o $@ $(LIBS)
23
24$(COBJS): %.o: %.c
25 $(CC) $(CFLAGS) $< -o $@
26
27$(CPPOBJS): %.o: %.cpp
28 $(CXX) $(CFLAGS) $< -o $@
29
30clean:
31 rm *.o testgui
32
33.PHONY: clean
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.linux b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.linux
new file mode 100644
index 0000000..d32e163
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.linux
@@ -0,0 +1,32 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: testgui
10
11CC=gcc
12CXX=g++
13COBJS=../libusb/hid.o
14CPPOBJS=test.o
15OBJS=$(COBJS) $(CPPOBJS)
16CFLAGS=-I../hidapi -Wall -g -c `fox-config --cflags` `pkg-config libusb-1.0 --cflags`
17LIBS=-ludev -lrt -lpthread `fox-config --libs` `pkg-config libusb-1.0 --libs`
18
19
20testgui: $(OBJS)
21 g++ -Wall -g $^ $(LIBS) -o testgui
22
23$(COBJS): %.o: %.c
24 $(CC) $(CFLAGS) $< -o $@
25
26$(CPPOBJS): %.o: %.cpp
27 $(CXX) $(CFLAGS) $< -o $@
28
29clean:
30 rm *.o testgui
31
32.PHONY: clean
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mac b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mac
new file mode 100644
index 0000000..cda7d49
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mac
@@ -0,0 +1,46 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-07-03
7###########################################
8
9all: hidapi-testgui
10
11CC=gcc
12CXX=g++
13COBJS=../mac/hid.o
14CPPOBJS=test.o
15OBJCOBJS=mac_support_cocoa.o
16OBJS=$(COBJS) $(CPPOBJS) $(OBJCOBJS)
17CFLAGS=-I../hidapi -Wall -g -c `fox-config --cflags`
18LDFLAGS=-L/usr/X11R6/lib
19LIBS=`fox-config --libs` -framework IOKit -framework CoreFoundation -framework Cocoa
20
21
22hidapi-testgui: $(OBJS) TestGUI.app
23 g++ -Wall -g $(OBJS) $(LIBS) $(LDFLAGS) -o hidapi-testgui
24 ./copy_to_bundle.sh
25 #cp TestGUI.app/Contents/MacOS/hidapi-testgui TestGUI.app/Contents/MacOS/tg
26 #cp start.sh TestGUI.app/Contents/MacOS/hidapi-testgui
27
28$(COBJS): %.o: %.c
29 $(CC) $(CFLAGS) $< -o $@
30
31$(CPPOBJS): %.o: %.cpp
32 $(CXX) $(CFLAGS) $< -o $@
33
34$(OBJCOBJS): %.o: %.m
35 $(CXX) $(CFLAGS) -x objective-c++ $< -o $@
36
37TestGUI.app: TestGUI.app.in
38 rm -Rf TestGUI.app
39 mkdir -p TestGUI.app
40 cp -R TestGUI.app.in/ TestGUI.app
41
42clean:
43 rm -f $(OBJS) hidapi-testgui
44 rm -Rf TestGUI.app
45
46.PHONY: clean
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mingw b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mingw
new file mode 100644
index 0000000..f76b5a0
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/Makefile.mingw
@@ -0,0 +1,32 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: hidapi-testgui
10
11CC=gcc
12CXX=g++
13COBJS=../windows/hid.o
14CPPOBJS=test.o
15OBJS=$(COBJS) $(CPPOBJS)
16CFLAGS=-I../hidapi -I../../hidapi-externals/fox/include -g -c
17LIBS= -mwindows -L../../hidapi-externals/fox/lib -Wl,-Bstatic -lFOX-1.6 -Wl,-Bdynamic -lgdi32 -Wl,--enable-auto-import -static-libgcc -static-libstdc++ -lkernel32
18
19
20hidapi-testgui: $(OBJS)
21 g++ -g $^ $(LIBS) -o hidapi-testgui
22
23$(COBJS): %.o: %.c
24 $(CC) $(CFLAGS) $< -o $@
25
26$(CPPOBJS): %.o: %.cpp
27 $(CXX) $(CFLAGS) $< -o $@
28
29clean:
30 rm -f *.o hidapi-testgui.exe
31
32.PHONY: clean
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist
new file mode 100644
index 0000000..ab473d5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist
@@ -0,0 +1,28 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4<dict>
5 <key>CFBundleDevelopmentRegion</key>
6 <string>English</string>
7 <key>CFBundleDisplayName</key>
8 <string></string>
9 <key>CFBundleExecutable</key>
10 <string>hidapi-testgui</string>
11 <key>CFBundleIconFile</key>
12 <string>Signal11.icns</string>
13 <key>CFBundleIdentifier</key>
14 <string>us.signal11.hidtestgui</string>
15 <key>CFBundleInfoDictionaryVersion</key>
16 <string>6.0</string>
17 <key>CFBundleName</key>
18 <string>testgui</string>
19 <key>CFBundlePackageType</key>
20 <string>APPL</string>
21 <key>CFBundleSignature</key>
22 <string>????</string>
23 <key>CFBundleVersion</key>
24 <string>1.0</string>
25 <key>CSResourcesFileMapped</key>
26 <true/>
27</dict>
28</plist>
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo
new file mode 100644
index 0000000..bd04210
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo
@@ -0,0 +1 @@
APPL???? \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..dea12de
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns
new file mode 100644
index 0000000..bb6b7bd
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns
Binary files differ
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/copy_to_bundle.sh b/contrib/SDL-3.2.8/src/hidapi/testgui/copy_to_bundle.sh
new file mode 100755
index 0000000..ddff64f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/copy_to_bundle.sh
@@ -0,0 +1,98 @@
1#!/bin/bash
2
3#### Configuration:
4# The name of the executable. It is assumed
5# that it is in the current working directory.
6EXE_NAME=hidapi-testgui
7# Path to the executable directory inside the bundle.
8# This must be an absolute path, so use $PWD.
9EXEPATH=$PWD/TestGUI.app/Contents/MacOS
10# Libraries to explicitly bundle, even though they
11# may not be in /opt/local. One per line. These
12# are used with grep, so only a portion of the name
13# is required. eg: libFOX, libz, etc.
14LIBS_TO_BUNDLE=libFOX
15
16
17function copydeps {
18 local file=$1
19 # echo "Copying deps for $file...."
20 local BASE_OF_EXE=`basename $file`
21
22 # A will contain the dependencies of this library
23 local A=`otool -LX $file |cut -f 1 -d " "`
24 local i
25 for i in $A; do
26 local BASE=`basename $i`
27
28 # See if it's a lib we specifically want to bundle
29 local bundle_this_lib=0
30 local j
31 for j in $LIBS_TO_BUNDLE; do
32 echo $i |grep -q $j
33 if [ $? -eq 0 ]; then
34 bundle_this_lib=1
35 echo "bundling $i because it's in the list."
36 break;
37 fi
38 done
39
40 # See if it's in /opt/local. Bundle all in /opt/local
41 local isOptLocal=0
42 echo $i |grep -q /opt/local
43 if [ $? -eq 0 ]; then
44 isOptLocal=1
45 echo "bundling $i because it's in /opt/local."
46 fi
47
48 # Bundle the library
49 if [ $isOptLocal -ne 0 ] || [ $bundle_this_lib -ne 0 ]; then
50
51 # Copy the file into the bundle if it exists.
52 if [ -f $EXEPATH/$BASE ]; then
53 z=0
54 else
55 cp $i $EXEPATH
56 chmod 755 $EXEPATH/$BASE
57 fi
58
59
60 # echo "$BASE_OF_EXE depends on $BASE"
61
62 # Fix the paths using install_name_tool and then
63 # call this function recursively for each dependency
64 # of this library.
65 if [ $BASE_OF_EXE != $BASE ]; then
66
67 # Fix the paths
68 install_name_tool -id @executable_path/$BASE $EXEPATH/$BASE
69 install_name_tool -change $i @executable_path/$BASE $EXEPATH/$BASE_OF_EXE
70
71 # Call this function (recursive) on
72 # on each dependency of this library.
73 copydeps $EXEPATH/$BASE
74 fi
75 fi
76 done
77}
78
79rm -f $EXEPATH/*
80mkdir -p $EXEPATH
81
82# Copy the binary into the bundle. Use ../libtool to do this if it's
83# available because if $EXE_NAME was built with autotools, it will be
84# necessary. If ../libtool not available, just use cp to do the copy, but
85# only if $EXE_NAME is a binary.
86if [ -x ../libtool ]; then
87 ../libtool --mode=install cp $EXE_NAME $EXEPATH
88else
89 file -bI $EXE_NAME |grep binary
90 if [ $? -ne 0 ]; then
91 echo "There is no ../libtool and $EXE_NAME is not a binary."
92 echo "I'm not sure what to do."
93 exit 1
94 else
95 cp $EXE_NAME $EXEPATH
96 fi
97fi
98copydeps $EXEPATH/$EXE_NAME
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/mac_support.h b/contrib/SDL-3.2.8/src/hidapi/testgui/mac_support.h
new file mode 100644
index 0000000..7d9ab49
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/mac_support.h
@@ -0,0 +1,17 @@
1/*******************************
2 Mac support for HID Test GUI
3
4 Alan Ott
5 Signal 11 Software
6
7*******************************/
8
9#ifndef MAC_SUPPORT_H__
10#define MAC_SUPPORT_H__
11
12extern "C" {
13 void init_apple_message_system();
14 void check_apple_events();
15}
16
17#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/mac_support_cocoa.m b/contrib/SDL-3.2.8/src/hidapi/testgui/mac_support_cocoa.m
new file mode 100644
index 0000000..1b12163
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/mac_support_cocoa.m
@@ -0,0 +1,103 @@
1/*******************************
2 Mac support for HID Test GUI
3
4 Alan Ott
5 Signal 11 Software
6*******************************/
7
8#include <fx.h>
9#import <Cocoa/Cocoa.h>
10
11#ifndef MAC_OS_X_VERSION_10_12
12#define MAC_OS_X_VERSION_10_12 101200
13#endif
14
15// macOS 10.12 deprecated NSAnyEventMask in favor of NSEventMaskAny
16#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
17#define NSEventMaskAny NSAnyEventMask
18#endif
19
20extern FXMainWindow *g_main_window;
21
22
23@interface MyAppDelegate : NSObject<NSApplicationDelegate>
24{
25}
26@end
27
28@implementation MyAppDelegate
29- (void) applicationWillBecomeActive:(NSNotification*)notif
30{
31 printf("WillBecomeActive\n");
32 g_main_window->show();
33
34}
35
36- (void) applicationWillTerminate:(NSNotification*)notif
37{
38 /* Doesn't get called. Not sure why */
39 printf("WillTerminate\n");
40 FXApp::instance()->exit();
41}
42
43- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication*)sender
44{
45 /* Doesn't get called. Not sure why */
46 printf("ShouldTerminate\n");
47 return YES;
48}
49
50- (void) applicationWillHide:(NSNotification*)notif
51{
52 printf("WillHide\n");
53 g_main_window->hide();
54}
55
56- (void) handleQuitEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
57{
58 printf("QuitEvent\n");
59 FXApp::instance()->exit();
60}
61
62@end
63
64extern "C" {
65
66void
67init_apple_message_system()
68{
69 static MyAppDelegate *d = [MyAppDelegate new];
70
71 [[NSApplication sharedApplication] setDelegate:d];
72
73 /* Register for Apple Events. */
74 /* This is from
75 http://stackoverflow.com/questions/1768497/application-exit-event */
76 NSAppleEventManager *aem = [NSAppleEventManager sharedAppleEventManager];
77 [aem setEventHandler:d
78 andSelector:@selector(handleQuitEvent:withReplyEvent:)
79 forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
80}
81
82void
83check_apple_events()
84{
85 NSApplication *app = [NSApplication sharedApplication];
86
87 NSAutoreleasePool *pool = [NSAutoreleasePool new];
88 while (1) {
89 NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
90 untilDate:nil
91 inMode:NSDefaultRunLoopMode
92 dequeue:YES];
93 if (event == NULL)
94 break;
95 else {
96 //printf("Event happened: Type: %d\n", event->_type);
97 [app sendEvent: event];
98 }
99 }
100 [pool release];
101}
102
103} /* extern "C" */
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/test.cpp b/contrib/SDL-3.2.8/src/hidapi/testgui/test.cpp
new file mode 100644
index 0000000..538db79
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/test.cpp
@@ -0,0 +1,532 @@
1/*******************************************************
2 Demo Program for HIDAPI
3
4 Alan Ott
5 Signal 11 Software
6
7 2010-07-20
8
9 Copyright 2010, All Rights Reserved
10
11 This contents of this file may be used by anyone
12 for any reason without any conditions and may be
13 used as a starting point for your own applications
14 which use HIDAPI.
15********************************************************/
16
17
18#include <fx.h>
19
20#include "hidapi.h"
21#include "mac_support.h"
22#include <string.h>
23#include <stdlib.h>
24#include <limits.h>
25
26#ifdef _WIN32
27 // Thanks Microsoft, but I know how to use strncpy().
28 #pragma warning(disable:4996)
29#endif
30
31class MainWindow : public FXMainWindow {
32 FXDECLARE(MainWindow)
33
34public:
35 enum {
36 ID_FIRST = FXMainWindow::ID_LAST,
37 ID_CONNECT,
38 ID_DISCONNECT,
39 ID_RESCAN,
40 ID_SEND_OUTPUT_REPORT,
41 ID_SEND_FEATURE_REPORT,
42 ID_GET_FEATURE_REPORT,
43 ID_CLEAR,
44 ID_TIMER,
45 ID_MAC_TIMER,
46 ID_LAST,
47 };
48
49private:
50 FXList *device_list;
51 FXButton *connect_button;
52 FXButton *disconnect_button;
53 FXButton *rescan_button;
54 FXButton *output_button;
55 FXLabel *connected_label;
56 FXTextField *output_text;
57 FXTextField *output_len;
58 FXButton *feature_button;
59 FXButton *get_feature_button;
60 FXTextField *feature_text;
61 FXTextField *feature_len;
62 FXTextField *get_feature_text;
63 FXText *input_text;
64 FXFont *title_font;
65
66 struct hid_device_info *devices;
67 hid_device *connected_device;
68 size_t getDataFromTextField(FXTextField *tf, char *buf, size_t len);
69 int getLengthFromTextField(FXTextField *tf);
70
71
72protected:
73 MainWindow() {};
74public:
75 MainWindow(FXApp *a);
76 ~MainWindow();
77 virtual void create();
78
79 long onConnect(FXObject *sender, FXSelector sel, void *ptr);
80 long onDisconnect(FXObject *sender, FXSelector sel, void *ptr);
81 long onRescan(FXObject *sender, FXSelector sel, void *ptr);
82 long onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr);
83 long onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
84 long onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
85 long onClear(FXObject *sender, FXSelector sel, void *ptr);
86 long onTimeout(FXObject *sender, FXSelector sel, void *ptr);
87 long onMacTimeout(FXObject *sender, FXSelector sel, void *ptr);
88};
89
90// FOX 1.7 changes the timeouts to all be nanoseconds.
91// Fox 1.6 had all timeouts as milliseconds.
92#if (FOX_MINOR >= 7)
93 const int timeout_scalar = 1000*1000;
94#else
95 const int timeout_scalar = 1;
96#endif
97
98FXMainWindow *g_main_window;
99
100
101FXDEFMAP(MainWindow) MainWindowMap [] = {
102 FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CONNECT, MainWindow::onConnect ),
103 FXMAPFUNC(SEL_COMMAND, MainWindow::ID_DISCONNECT, MainWindow::onDisconnect ),
104 FXMAPFUNC(SEL_COMMAND, MainWindow::ID_RESCAN, MainWindow::onRescan ),
105 FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_OUTPUT_REPORT, MainWindow::onSendOutputReport ),
106 FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_FEATURE_REPORT, MainWindow::onSendFeatureReport ),
107 FXMAPFUNC(SEL_COMMAND, MainWindow::ID_GET_FEATURE_REPORT, MainWindow::onGetFeatureReport ),
108 FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CLEAR, MainWindow::onClear ),
109 FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_TIMER, MainWindow::onTimeout ),
110 FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_MAC_TIMER, MainWindow::onMacTimeout ),
111};
112
113FXIMPLEMENT(MainWindow, FXMainWindow, MainWindowMap, ARRAYNUMBER(MainWindowMap));
114
115MainWindow::MainWindow(FXApp *app)
116 : FXMainWindow(app, "HIDAPI Test Application", NULL, NULL, DECOR_ALL, 200,100, 425,700)
117{
118 devices = NULL;
119 connected_device = NULL;
120
121 FXVerticalFrame *vf = new FXVerticalFrame(this, LAYOUT_FILL_Y|LAYOUT_FILL_X);
122
123 FXLabel *label = new FXLabel(vf, "HIDAPI Test Tool");
124 title_font = new FXFont(getApp(), "Arial", 14, FXFont::Bold);
125 label->setFont(title_font);
126
127 new FXLabel(vf,
128 "Select a device and press Connect.", NULL, JUSTIFY_LEFT);
129 new FXLabel(vf,
130 "Output data bytes can be entered in the Output section, \n"
131 "separated by space, comma or brackets. Data starting with 0x\n"
132 "is treated as hex. Data beginning with a 0 is treated as \n"
133 "octal. All other data is treated as decimal.", NULL, JUSTIFY_LEFT);
134 new FXLabel(vf,
135 "Data received from the device appears in the Input section.",
136 NULL, JUSTIFY_LEFT);
137 new FXLabel(vf,
138 "Optionally, a report length may be specified. Extra bytes are\n"
139 "padded with zeros. If no length is specified, the length is \n"
140 "inferred from the data.",
141 NULL, JUSTIFY_LEFT);
142 new FXLabel(vf, "");
143
144 // Device List and Connect/Disconnect buttons
145 FXHorizontalFrame *hf = new FXHorizontalFrame(vf, LAYOUT_FILL_X);
146 //device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0,0,300,200);
147 device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,300,200);
148 FXVerticalFrame *buttonVF = new FXVerticalFrame(hf);
149 connect_button = new FXButton(buttonVF, "Connect", NULL, this, ID_CONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
150 disconnect_button = new FXButton(buttonVF, "Disconnect", NULL, this, ID_DISCONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
151 disconnect_button->disable();
152 rescan_button = new FXButton(buttonVF, "Re-Scan devices", NULL, this, ID_RESCAN, BUTTON_NORMAL|LAYOUT_FILL_X);
153 new FXHorizontalFrame(buttonVF, 0, 0,0,0,0, 0,0,50,0);
154
155 connected_label = new FXLabel(vf, "Disconnected");
156
157 new FXHorizontalFrame(vf);
158
159 // Output Group Box
160 FXGroupBox *gb = new FXGroupBox(vf, "Output", FRAME_GROOVE|LAYOUT_FILL_X);
161 FXMatrix *matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
162 new FXLabel(matrix, "Data");
163 new FXLabel(matrix, "Length");
164 new FXLabel(matrix, "");
165
166 //hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
167 output_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
168 output_text->setText("1 0x81 0");
169 output_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
170 output_button = new FXButton(matrix, "Send Output Report", NULL, this, ID_SEND_OUTPUT_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
171 output_button->disable();
172 //new FXHorizontalFrame(matrix, LAYOUT_FILL_X);
173
174 //hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
175 feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
176 feature_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
177 feature_button = new FXButton(matrix, "Send Feature Report", NULL, this, ID_SEND_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
178 feature_button->disable();
179
180 get_feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
181 new FXWindow(matrix);
182 get_feature_button = new FXButton(matrix, "Get Feature Report", NULL, this, ID_GET_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
183 get_feature_button->disable();
184
185
186 // Input Group Box
187 gb = new FXGroupBox(vf, "Input", FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
188 FXVerticalFrame *innerVF = new FXVerticalFrame(gb, LAYOUT_FILL_X|LAYOUT_FILL_Y);
189 input_text = new FXText(new FXHorizontalFrame(innerVF,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y);
190 input_text->setEditable(false);
191 new FXButton(innerVF, "Clear", NULL, this, ID_CLEAR, BUTTON_NORMAL|LAYOUT_RIGHT);
192
193
194}
195
196MainWindow::~MainWindow()
197{
198 if (connected_device)
199 hid_close(connected_device);
200 hid_exit();
201 delete title_font;
202}
203
204void
205MainWindow::create()
206{
207 FXMainWindow::create();
208 show();
209
210 onRescan(NULL, 0, NULL);
211
212
213#ifdef __APPLE__
214 init_apple_message_system();
215#endif
216
217 getApp()->addTimeout(this, ID_MAC_TIMER,
218 50 * timeout_scalar /*50ms*/);
219}
220
221long
222MainWindow::onConnect(FXObject *sender, FXSelector sel, void *ptr)
223{
224 if (connected_device != NULL)
225 return 1;
226
227 FXint cur_item = device_list->getCurrentItem();
228 if (cur_item < 0)
229 return -1;
230 FXListItem *item = device_list->getItem(cur_item);
231 if (!item)
232 return -1;
233 struct hid_device_info *device_info = (struct hid_device_info*) item->getData();
234 if (!device_info)
235 return -1;
236
237 connected_device = hid_open_path(device_info->path);
238
239 if (!connected_device) {
240 FXMessageBox::error(this, MBOX_OK, "Device Error", "Unable To Connect to Device");
241 return -1;
242 }
243
244 hid_set_nonblocking(connected_device, 1);
245
246 getApp()->addTimeout(this, ID_TIMER,
247 5 * timeout_scalar /*5ms*/);
248
249 FXString s;
250 s.format("Connected to: %04hx:%04hx -", device_info->vendor_id, device_info->product_id);
251 s += FXString(" ") + device_info->manufacturer_string;
252 s += FXString(" ") + device_info->product_string;
253 connected_label->setText(s);
254 output_button->enable();
255 feature_button->enable();
256 get_feature_button->enable();
257 connect_button->disable();
258 disconnect_button->enable();
259 input_text->setText("");
260
261
262 return 1;
263}
264
265long
266MainWindow::onDisconnect(FXObject *sender, FXSelector sel, void *ptr)
267{
268 hid_close(connected_device);
269 connected_device = NULL;
270 connected_label->setText("Disconnected");
271 output_button->disable();
272 feature_button->disable();
273 get_feature_button->disable();
274 connect_button->enable();
275 disconnect_button->disable();
276
277 getApp()->removeTimeout(this, ID_TIMER);
278
279 return 1;
280}
281
282long
283MainWindow::onRescan(FXObject *sender, FXSelector sel, void *ptr)
284{
285 struct hid_device_info *cur_dev;
286
287 device_list->clearItems();
288
289 // List the Devices
290 hid_free_enumeration(devices);
291 devices = hid_enumerate(0x0, 0x0);
292 cur_dev = devices;
293 while (cur_dev) {
294 // Add it to the List Box.
295 FXString s;
296 FXString usage_str;
297 s.format("%04hx:%04hx -", cur_dev->vendor_id, cur_dev->product_id);
298 s += FXString(" ") + cur_dev->manufacturer_string;
299 s += FXString(" ") + cur_dev->product_string;
300 usage_str.format(" (usage: %04hx:%04hx) ", cur_dev->usage_page, cur_dev->usage);
301 s += usage_str;
302 FXListItem *li = new FXListItem(s, NULL, cur_dev);
303 device_list->appendItem(li);
304
305 cur_dev = cur_dev->next;
306 }
307
308 if (device_list->getNumItems() == 0)
309 device_list->appendItem("*** No Devices Connected ***");
310 else {
311 device_list->selectItem(0);
312 }
313
314 return 1;
315}
316
317size_t
318MainWindow::getDataFromTextField(FXTextField *tf, char *buf, size_t len)
319{
320 const char *delim = " ,{}\t\r\n";
321 FXString data = tf->getText();
322 const FXchar *d = data.text();
323 size_t i = 0;
324
325 // Copy the string from the GUI.
326 size_t sz = strlen(d);
327 char *str = (char*) malloc(sz+1);
328 strcpy(str, d);
329
330 // For each token in the string, parse and store in buf[].
331 char *token = strtok(str, delim);
332 while (token) {
333 char *endptr;
334 long int val = strtol(token, &endptr, 0);
335 buf[i++] = val;
336 token = strtok(NULL, delim);
337 }
338
339 free(str);
340 return i;
341}
342
343/* getLengthFromTextField()
344 Returns length:
345 0: empty text field
346 >0: valid length
347 -1: invalid length */
348int
349MainWindow::getLengthFromTextField(FXTextField *tf)
350{
351 long int len;
352 FXString str = tf->getText();
353 size_t sz = str.length();
354
355 if (sz > 0) {
356 char *endptr;
357 len = strtol(str.text(), &endptr, 0);
358 if (endptr != str.text() && *endptr == '\0') {
359 if (len <= 0) {
360 FXMessageBox::error(this, MBOX_OK, "Invalid length", "Enter a length greater than zero.");
361 return -1;
362 }
363 return len;
364 }
365 else
366 return -1;
367 }
368
369 return 0;
370}
371
372long
373MainWindow::onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr)
374{
375 char buf[256];
376 size_t data_len, len;
377 int textfield_len;
378
379 memset(buf, 0x0, sizeof(buf));
380 textfield_len = getLengthFromTextField(output_len);
381 data_len = getDataFromTextField(output_text, buf, sizeof(buf));
382
383 if (textfield_len < 0) {
384 FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
385 return 1;
386 }
387
388 if (textfield_len > sizeof(buf)) {
389 FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
390 return 1;
391 }
392
393 len = (textfield_len)? textfield_len: data_len;
394
395 int res = hid_write(connected_device, (const unsigned char*)buf, len);
396 if (res < 0) {
397 FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not write to device. Error reported was: %ls", hid_error(connected_device));
398 }
399
400 return 1;
401}
402
403long
404MainWindow::onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
405{
406 char buf[256];
407 size_t data_len, len;
408 int textfield_len;
409
410 memset(buf, 0x0, sizeof(buf));
411 textfield_len = getLengthFromTextField(feature_len);
412 data_len = getDataFromTextField(feature_text, buf, sizeof(buf));
413
414 if (textfield_len < 0) {
415 FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
416 return 1;
417 }
418
419 if (textfield_len > sizeof(buf)) {
420 FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
421 return 1;
422 }
423
424 len = (textfield_len)? textfield_len: data_len;
425
426 int res = hid_send_feature_report(connected_device, (const unsigned char*)buf, len);
427 if (res < 0) {
428 FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not send feature report to device. Error reported was: %ls", hid_error(connected_device));
429 }
430
431 return 1;
432}
433
434long
435MainWindow::onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
436{
437 char buf[256];
438 size_t len;
439
440 memset(buf, 0x0, sizeof(buf));
441 len = getDataFromTextField(get_feature_text, buf, sizeof(buf));
442
443 if (len != 1) {
444 FXMessageBox::error(this, MBOX_OK, "Too many numbers", "Enter only a single report number in the text field");
445 }
446
447 int res = hid_get_feature_report(connected_device, (unsigned char*)buf, sizeof(buf));
448 if (res < 0) {
449 FXMessageBox::error(this, MBOX_OK, "Error Getting Report", "Could not get feature report from device. Error reported was: %ls", hid_error(connected_device));
450 }
451
452 if (res > 0) {
453 FXString s;
454 s.format("Returned Feature Report. %d bytes:\n", res);
455 for (int i = 0; i < res; i++) {
456 FXString t;
457 t.format("%02hhx ", buf[i]);
458 s += t;
459 if ((i+1) % 4 == 0)
460 s += " ";
461 if ((i+1) % 16 == 0)
462 s += "\n";
463 }
464 s += "\n";
465 input_text->appendText(s);
466 input_text->setBottomLine(INT_MAX);
467 }
468
469 return 1;
470}
471
472long
473MainWindow::onClear(FXObject *sender, FXSelector sel, void *ptr)
474{
475 input_text->setText("");
476 return 1;
477}
478
479long
480MainWindow::onTimeout(FXObject *sender, FXSelector sel, void *ptr)
481{
482 unsigned char buf[256];
483 int res = hid_read(connected_device, buf, sizeof(buf));
484
485 if (res > 0) {
486 FXString s;
487 s.format("Received %d bytes:\n", res);
488 for (int i = 0; i < res; i++) {
489 FXString t;
490 t.format("%02hhx ", buf[i]);
491 s += t;
492 if ((i+1) % 4 == 0)
493 s += " ";
494 if ((i+1) % 16 == 0)
495 s += "\n";
496 }
497 s += "\n";
498 input_text->appendText(s);
499 input_text->setBottomLine(INT_MAX);
500 }
501 if (res < 0) {
502 input_text->appendText("hid_read() returned error\n");
503 input_text->setBottomLine(INT_MAX);
504 }
505
506 getApp()->addTimeout(this, ID_TIMER,
507 5 * timeout_scalar /*5ms*/);
508 return 1;
509}
510
511long
512MainWindow::onMacTimeout(FXObject *sender, FXSelector sel, void *ptr)
513{
514#ifdef __APPLE__
515 check_apple_events();
516
517 getApp()->addTimeout(this, ID_MAC_TIMER,
518 50 * timeout_scalar /*50ms*/);
519#endif
520
521 return 1;
522}
523
524int main(int argc, char **argv)
525{
526 FXApp app("HIDAPI Test Application", "Signal 11 Software");
527 app.init(argc, argv);
528 g_main_window = new MainWindow(&app);
529 app.create();
530 app.run();
531 return 0;
532}
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/testgui.sln b/contrib/SDL-3.2.8/src/hidapi/testgui/testgui.sln
new file mode 100644
index 0000000..56be6c6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/testgui.sln
@@ -0,0 +1,20 @@
1
2Microsoft Visual Studio Solution File, Format Version 10.00
3# Visual C++ Express 2008
4Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgui", "testgui.vcproj", "{08769AC3-785A-4DDC-BFC7-1775414B7AB7}"
5EndProject
6Global
7 GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 Debug|Win32 = Debug|Win32
9 Release|Win32 = Release|Win32
10 EndGlobalSection
11 GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 {08769AC3-785A-4DDC-BFC7-1775414B7AB7}.Debug|Win32.ActiveCfg = Debug|Win32
13 {08769AC3-785A-4DDC-BFC7-1775414B7AB7}.Debug|Win32.Build.0 = Debug|Win32
14 {08769AC3-785A-4DDC-BFC7-1775414B7AB7}.Release|Win32.ActiveCfg = Release|Win32
15 {08769AC3-785A-4DDC-BFC7-1775414B7AB7}.Release|Win32.Build.0 = Release|Win32
16 EndGlobalSection
17 GlobalSection(SolutionProperties) = preSolution
18 HideSolutionNode = FALSE
19 EndGlobalSection
20EndGlobal
diff --git a/contrib/SDL-3.2.8/src/hidapi/testgui/testgui.vcproj b/contrib/SDL-3.2.8/src/hidapi/testgui/testgui.vcproj
new file mode 100644
index 0000000..f6e6c09
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/testgui/testgui.vcproj
@@ -0,0 +1,217 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="9.00"
5 Name="testgui"
6 ProjectGUID="{08769AC3-785A-4DDC-BFC7-1775414B7AB7}"
7 RootNamespace="testgui"
8 Keyword="Win32Proj"
9 TargetFrameworkVersion="196613"
10 >
11 <Platforms>
12 <Platform
13 Name="Win32"
14 />
15 </Platforms>
16 <ToolFiles>
17 </ToolFiles>
18 <Configurations>
19 <Configuration
20 Name="Debug|Win32"
21 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
22 IntermediateDirectory="$(ConfigurationName)"
23 ConfigurationType="1"
24 CharacterSet="1"
25 >
26 <Tool
27 Name="VCPreBuildEventTool"
28 />
29 <Tool
30 Name="VCCustomBuildTool"
31 />
32 <Tool
33 Name="VCXMLDataGeneratorTool"
34 />
35 <Tool
36 Name="VCWebServiceProxyGeneratorTool"
37 />
38 <Tool
39 Name="VCMIDLTool"
40 />
41 <Tool
42 Name="VCCLCompilerTool"
43 Optimization="0"
44 AdditionalIncludeDirectories="&quot;..\..\hidapi-externals\fox\include&quot;;..\hidapi"
45 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
46 MinimalRebuild="true"
47 BasicRuntimeChecks="3"
48 RuntimeLibrary="3"
49 UsePrecompiledHeader="0"
50 WarningLevel="3"
51 DebugInformationFormat="4"
52 />
53 <Tool
54 Name="VCManagedResourceCompilerTool"
55 />
56 <Tool
57 Name="VCResourceCompilerTool"
58 />
59 <Tool
60 Name="VCPreLinkEventTool"
61 />
62 <Tool
63 Name="VCLinkerTool"
64 AdditionalDependencies="fox-1.6.lib"
65 OutputFile="$(ProjectName).exe"
66 LinkIncremental="2"
67 AdditionalLibraryDirectories="..\hidapi\objfre_wxp_x86\i386;&quot;..\..\hidapi-externals\fox\lib&quot;"
68 GenerateDebugInformation="true"
69 SubSystem="2"
70 EntryPointSymbol="mainCRTStartup"
71 TargetMachine="1"
72 />
73 <Tool
74 Name="VCALinkTool"
75 />
76 <Tool
77 Name="VCManifestTool"
78 />
79 <Tool
80 Name="VCXDCMakeTool"
81 />
82 <Tool
83 Name="VCBscMakeTool"
84 />
85 <Tool
86 Name="VCFxCopTool"
87 />
88 <Tool
89 Name="VCAppVerifierTool"
90 />
91 <Tool
92 Name="VCPostBuildEventTool"
93 CommandLine=""
94 />
95 </Configuration>
96 <Configuration
97 Name="Release|Win32"
98 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
99 IntermediateDirectory="$(ConfigurationName)"
100 ConfigurationType="1"
101 CharacterSet="1"
102 WholeProgramOptimization="1"
103 >
104 <Tool
105 Name="VCPreBuildEventTool"
106 />
107 <Tool
108 Name="VCCustomBuildTool"
109 />
110 <Tool
111 Name="VCXMLDataGeneratorTool"
112 />
113 <Tool
114 Name="VCWebServiceProxyGeneratorTool"
115 />
116 <Tool
117 Name="VCMIDLTool"
118 />
119 <Tool
120 Name="VCCLCompilerTool"
121 Optimization="2"
122 EnableIntrinsicFunctions="true"
123 AdditionalIncludeDirectories="&quot;..\..\hidapi-externals\fox\include&quot;;..\hidapi"
124 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
125 RuntimeLibrary="2"
126 EnableFunctionLevelLinking="true"
127 UsePrecompiledHeader="0"
128 WarningLevel="3"
129 DebugInformationFormat="3"
130 />
131 <Tool
132 Name="VCManagedResourceCompilerTool"
133 />
134 <Tool
135 Name="VCResourceCompilerTool"
136 />
137 <Tool
138 Name="VCPreLinkEventTool"
139 />
140 <Tool
141 Name="VCLinkerTool"
142 AdditionalDependencies="fox-1.6.lib"
143 OutputFile="$(ProjectName).exe"
144 LinkIncremental="1"
145 AdditionalLibraryDirectories="..\hidapi\objfre_wxp_x86\i386;&quot;..\..\hidapi-externals\fox\lib&quot;"
146 GenerateDebugInformation="true"
147 SubSystem="2"
148 OptimizeReferences="2"
149 EnableCOMDATFolding="2"
150 EntryPointSymbol="mainCRTStartup"
151 TargetMachine="1"
152 />
153 <Tool
154 Name="VCALinkTool"
155 />
156 <Tool
157 Name="VCManifestTool"
158 />
159 <Tool
160 Name="VCXDCMakeTool"
161 />
162 <Tool
163 Name="VCBscMakeTool"
164 />
165 <Tool
166 Name="VCFxCopTool"
167 />
168 <Tool
169 Name="VCAppVerifierTool"
170 />
171 <Tool
172 Name="VCPostBuildEventTool"
173 CommandLine=""
174 />
175 </Configuration>
176 </Configurations>
177 <References>
178 </References>
179 <Files>
180 <Filter
181 Name="Source Files"
182 Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
183 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
184 >
185 <File
186 RelativePath="..\windows\hid.c"
187 >
188 </File>
189 <File
190 RelativePath=".\test.cpp"
191 >
192 </File>
193 </Filter>
194 <Filter
195 Name="Header Files"
196 Filter="h;hpp;hxx;hm;inl;inc;xsd"
197 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
198 >
199 <File
200 RelativePath="..\hidapi\hidapi.h"
201 >
202 </File>
203 </Filter>
204 <Filter
205 Name="Resource Files"
206 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
207 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
208 >
209 </Filter>
210 <File
211 RelativePath=".\ReadMe.txt"
212 >
213 </File>
214 </Files>
215 <Globals>
216 </Globals>
217</VisualStudioProject>
diff --git a/contrib/SDL-3.2.8/src/hidapi/udev/69-hid.rules b/contrib/SDL-3.2.8/src/hidapi/udev/69-hid.rules
new file mode 100644
index 0000000..02d6a2c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/udev/69-hid.rules
@@ -0,0 +1,36 @@
1# This is a sample udev file for HIDAPI devices which lets unprivileged
2# users who are physically present at the system (not remote users) access
3# HID devices.
4
5# If you are using the libusb implementation of hidapi (libusb/hid.c), then
6# use something like the following line, substituting the VID and PID with
7# those of your device.
8
9# HIDAPI/libusb
10SUBSYSTEMS=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="003f", TAG+="uaccess"
11
12# If you are using the hidraw implementation (linux/hid.c), then do something
13# like the following, substituting the VID and PID with your device.
14
15# HIDAPI/hidraw
16KERNEL=="hidraw*", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="003f", TAG+="uaccess"
17
18# Once done, optionally rename this file for your application, and drop it into
19# /etc/udev/rules.d/.
20# NOTE: these rules must have priority before 73-seat-late.rules.
21# (Small discussion/explanation in systemd repo:
22# https://github.com/systemd/systemd/issues/4288#issuecomment-348166161)
23# for example, name the file /etc/udev/rules.d/70-my-application-hid.rules.
24# Then, replug your device or run:
25# sudo udevadm control --reload-rules && sudo udevadm trigger
26
27# Note that the hexadecimal values for VID and PID are case sensitive and
28# must be lower case.
29
30# TAG+="uaccess" only gives permission to physically present users, which
31# is appropriate in most scenarios. If you require access to the device
32# from a remote session (e.g. over SSH), add
33# GROUP="plugdev", MODE="660"
34# to the end of the udev rule lines, add your user to the plugdev group with:
35# usermod -aG plugdev USERNAME
36# then log out and log back in (or restart the system).
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/windows/CMakeLists.txt
new file mode 100644
index 0000000..c8228bc
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/CMakeLists.txt
@@ -0,0 +1,63 @@
1list(APPEND HIDAPI_PUBLIC_HEADERS "hidapi_winapi.h")
2
3set(SOURCES
4 hid.c
5 hidapi_cfgmgr32.h
6 hidapi_descriptor_reconstruct.c
7 hidapi_descriptor_reconstruct.h
8 hidapi_hidclass.h
9 hidapi_hidpi.h
10 hidapi_hidsdi.h
11)
12
13if(BUILD_SHARED_LIBS)
14 list(APPEND SOURCES hidapi.rc)
15endif()
16
17add_library(hidapi_winapi
18 ${HIDAPI_PUBLIC_HEADERS}
19 ${SOURCES}
20)
21target_link_libraries(hidapi_winapi
22 PUBLIC hidapi_include
23)
24
25if(NOT BUILD_SHARED_LIBS)
26 target_compile_definitions(hidapi_winapi
27 # prevent marking functions as __declspec(dllexport) for static library build
28 # #480: this should be refactored for v1.0
29 PUBLIC HID_API_NO_EXPORT_DEFINE
30 )
31endif()
32
33set_target_properties(hidapi_winapi
34 PROPERTIES
35 EXPORT_NAME "winapi"
36 OUTPUT_NAME "hidapi"
37 VERSION ${PROJECT_VERSION}
38 PUBLIC_HEADER "${HIDAPI_PUBLIC_HEADERS}"
39)
40
41# compatibility with find_package()
42add_library(hidapi::winapi ALIAS hidapi_winapi)
43# compatibility with raw library link
44add_library(hidapi ALIAS hidapi_winapi)
45
46if(HIDAPI_INSTALL_TARGETS)
47 install(TARGETS hidapi_winapi EXPORT hidapi
48 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
49 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
50 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
51 PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/hidapi"
52 )
53endif()
54
55hidapi_configure_pc("${PROJECT_ROOT}/pc/hidapi.pc.in")
56
57if(HIDAPI_WITH_TESTS)
58 add_subdirectory(test)
59endif()
60
61if(DEFINED HIDAPI_BUILD_PP_DATA_DUMP AND HIDAPI_BUILD_PP_DATA_DUMP)
62 add_subdirectory(pp_data_dump)
63endif()
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/Makefile-manual b/contrib/SDL-3.2.8/src/hidapi/windows/Makefile-manual
new file mode 100644
index 0000000..ac471d6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/Makefile-manual
@@ -0,0 +1,14 @@
1
2
3OS=$(shell uname)
4
5ifneq (,$(findstring MINGW,$(OS)))
6 FILE=Makefile.mingw
7endif
8
9ifeq ($(FILE), )
10all:
11 $(error Your platform ${OS} is not supported at this time.)
12endif
13
14include $(FILE)
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/Makefile.am b/contrib/SDL-3.2.8/src/hidapi/windows/Makefile.am
new file mode 100644
index 0000000..2ea5c0d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/Makefile.am
@@ -0,0 +1,15 @@
1lib_LTLIBRARIES = libhidapi.la
2libhidapi_la_SOURCES = hid.c
3libhidapi_la_LDFLAGS = $(LTLDFLAGS)
4AM_CPPFLAGS = -I$(top_srcdir)/hidapi/
5libhidapi_la_LIBADD = $(LIBS)
6
7hdrdir = $(includedir)/hidapi
8hdr_HEADERS = $(top_srcdir)/hidapi/hidapi.h
9
10EXTRA_DIST = \
11 hidapi.vcproj \
12 hidtest.vcproj \
13 Makefile-manual \
14 Makefile.mingw \
15 hidapi.sln
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/Makefile.mingw b/contrib/SDL-3.2.8/src/hidapi/windows/Makefile.mingw
new file mode 100644
index 0000000..857e4fb
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/Makefile.mingw
@@ -0,0 +1,30 @@
1###########################################
2# Simple Makefile for HIDAPI test program
3#
4# Alan Ott
5# Signal 11 Software
6# 2010-06-01
7###########################################
8
9all: hidtest libhidapi.dll
10
11CC=gcc
12COBJS=hid.o ../hidtest/test.o
13OBJS=$(COBJS)
14CFLAGS=-I../hidapi -I. -g -c
15LIBS=
16DLL_LDFLAGS = -mwindows
17
18hidtest: $(OBJS)
19 $(CC) -g $^ $(LIBS) -o hidtest
20
21libhidapi.dll: $(OBJS)
22 $(CC) -g $^ $(DLL_LDFLAGS) -o libhidapi.dll
23
24$(COBJS): %.o: %.c
25 $(CC) $(CFLAGS) $< -o $@
26
27clean:
28 rm *.o ../hidtest/*.o hidtest.exe
29
30.PHONY: clean
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hid.c b/contrib/SDL-3.2.8/src/hidapi/windows/hid.c
new file mode 100644
index 0000000..3376ba9
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hid.c
@@ -0,0 +1,1728 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Copyright 2022, All Rights Reserved.
11
12 At the discretion of the user of this library,
13 this software may be licensed under the terms of the
14 GNU General Public License v3, a BSD-Style license, or the
15 original HIDAPI license as outlined in the LICENSE.txt,
16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17 files located at the root of the source distribution.
18 These files may also be found in the public source
19 code repository located at:
20 https://github.com/libusb/hidapi .
21********************************************************/
22
23#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
24/* Do not warn about wcsncpy usage.
25 https://docs.microsoft.com/cpp/c-runtime-library/security-features-in-the-crt */
26#define _CRT_SECURE_NO_WARNINGS
27#endif
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#include "hidapi_winapi.h"
34
35#include <windows.h>
36
37#ifndef _NTDEF_
38typedef LONG NTSTATUS;
39#endif
40
41#ifndef WC_ERR_INVALID_CHARS
42#define WC_ERR_INVALID_CHARS 0x00000080
43#endif
44#ifndef _WIN32_WINNT_WIN8
45#define _WIN32_WINNT_WIN8 0x0602
46#endif
47
48#ifdef __CYGWIN__
49#include <ntdef.h>
50#include <wctype.h>
51#define _wcsdup wcsdup
52#endif
53
54/*#define HIDAPI_USE_DDK*/
55
56#include "hidapi_cfgmgr32.h"
57#include "hidapi_hidclass.h"
58#include "hidapi_hidsdi.h"
59
60#ifndef HIDAPI_USING_SDL_RUNTIME
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#endif
65
66#ifdef MIN
67#undef MIN
68#endif
69#define MIN(x,y) ((x) < (y)? (x): (y))
70
71/* MAXIMUM_USB_STRING_LENGTH from usbspec.h is 255 */
72/* BLUETOOTH_DEVICE_NAME_SIZE from bluetoothapis.h is 256 */
73#define MAX_STRING_WCHARS 256
74
75/* For certain USB devices, using a buffer larger or equal to 127 wchars results
76 in successful completion of HID API functions, but a broken string is stored
77 in the output buffer. This behaviour persists even if HID API is bypassed and
78 HID IOCTLs are passed to the HID driver directly. Therefore, for USB devices,
79 the buffer MUST NOT exceed 126 WCHARs.
80*/
81
82#define MAX_STRING_WCHARS_USB 126
83
84static struct hid_api_version api_version = {
85 .major = HID_API_VERSION_MAJOR,
86 .minor = HID_API_VERSION_MINOR,
87 .patch = HID_API_VERSION_PATCH
88};
89
90#ifndef HIDAPI_USE_DDK
91/* Since we're not building with the DDK, and the HID header
92 files aren't part of the Windows SDK, we define what we need ourselves.
93 In lookup_functions(), the function pointers
94 defined below are set. */
95
96static HidD_GetHidGuid_ HidD_GetHidGuid;
97static HidD_GetAttributes_ HidD_GetAttributes;
98static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
99static HidD_GetManufacturerString_ HidD_GetManufacturerString;
100static HidD_GetProductString_ HidD_GetProductString;
101static HidD_SetFeature_ HidD_SetFeature;
102static HidD_GetFeature_ HidD_GetFeature;
103static HidD_GetInputReport_ HidD_GetInputReport;
104static HidD_GetIndexedString_ HidD_GetIndexedString;
105static HidD_GetPreparsedData_ HidD_GetPreparsedData;
106static HidD_FreePreparsedData_ HidD_FreePreparsedData;
107static HidP_GetCaps_ HidP_GetCaps;
108static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
109static HidD_SetOutputReport_ HidD_SetOutputReport;
110
111static CM_Locate_DevNodeW_ CM_Locate_DevNodeW = NULL;
112static CM_Get_Parent_ CM_Get_Parent = NULL;
113static CM_Get_DevNode_PropertyW_ CM_Get_DevNode_PropertyW = NULL;
114static CM_Get_Device_Interface_PropertyW_ CM_Get_Device_Interface_PropertyW = NULL;
115static CM_Get_Device_Interface_List_SizeW_ CM_Get_Device_Interface_List_SizeW = NULL;
116static CM_Get_Device_Interface_ListW_ CM_Get_Device_Interface_ListW = NULL;
117
118static HMODULE hid_lib_handle = NULL;
119static HMODULE cfgmgr32_lib_handle = NULL;
120static BOOLEAN hidapi_initialized = FALSE;
121
122static void free_library_handles(void)
123{
124 if (hid_lib_handle)
125 FreeLibrary(hid_lib_handle);
126 hid_lib_handle = NULL;
127 if (cfgmgr32_lib_handle)
128 FreeLibrary(cfgmgr32_lib_handle);
129 cfgmgr32_lib_handle = NULL;
130}
131
132#if defined(__GNUC__) && __GNUC__ >= 8
133# pragma GCC diagnostic push
134# pragma GCC diagnostic ignored "-Wcast-function-type"
135#endif
136
137static int lookup_functions(void)
138{
139 hid_lib_handle = LoadLibraryW(L"hid.dll");
140 if (hid_lib_handle == NULL) {
141 goto err;
142 }
143
144 cfgmgr32_lib_handle = LoadLibraryW(L"cfgmgr32.dll");
145 if (cfgmgr32_lib_handle == NULL) {
146 goto err;
147 }
148
149#define RESOLVE(lib_handle, x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) goto err;
150
151 RESOLVE(hid_lib_handle, HidD_GetHidGuid);
152 RESOLVE(hid_lib_handle, HidD_GetAttributes);
153 RESOLVE(hid_lib_handle, HidD_GetSerialNumberString);
154 RESOLVE(hid_lib_handle, HidD_GetManufacturerString);
155 RESOLVE(hid_lib_handle, HidD_GetProductString);
156 RESOLVE(hid_lib_handle, HidD_SetFeature);
157 RESOLVE(hid_lib_handle, HidD_GetFeature);
158 RESOLVE(hid_lib_handle, HidD_GetInputReport);
159 RESOLVE(hid_lib_handle, HidD_GetIndexedString);
160 RESOLVE(hid_lib_handle, HidD_GetPreparsedData);
161 RESOLVE(hid_lib_handle, HidD_FreePreparsedData);
162 RESOLVE(hid_lib_handle, HidP_GetCaps);
163 RESOLVE(hid_lib_handle, HidD_SetNumInputBuffers);
164 RESOLVE(hid_lib_handle, HidD_SetOutputReport);
165
166 RESOLVE(cfgmgr32_lib_handle, CM_Locate_DevNodeW);
167 RESOLVE(cfgmgr32_lib_handle, CM_Get_Parent);
168 RESOLVE(cfgmgr32_lib_handle, CM_Get_DevNode_PropertyW);
169 RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_PropertyW);
170 RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_List_SizeW);
171 RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_ListW);
172
173#undef RESOLVE
174
175 return 0;
176
177err:
178 free_library_handles();
179 return -1;
180}
181
182#if defined(__GNUC__) && __GNUC__ >= 8
183# pragma GCC diagnostic pop
184#endif
185
186#endif /* HIDAPI_USE_DDK */
187
188struct hid_device_ {
189 HANDLE device_handle;
190 BOOL blocking;
191 USHORT output_report_length;
192 unsigned char *write_buf;
193 size_t input_report_length;
194 USHORT feature_report_length;
195 unsigned char *feature_buf;
196 wchar_t *last_error_str;
197 BOOL read_pending;
198 char *read_buf;
199 OVERLAPPED ol;
200 OVERLAPPED write_ol;
201 struct hid_device_info* device_info;
202 BOOL use_hid_write_output_report;
203};
204
205static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
206{
207 OSVERSIONINFOEXW osvi;
208 DWORDLONG const dwlConditionMask = VerSetConditionMask(
209 VerSetConditionMask(
210 VerSetConditionMask(
211 0, VER_MAJORVERSION, VER_GREATER_EQUAL ),
212 VER_MINORVERSION, VER_GREATER_EQUAL ),
213 VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL );
214
215 memset(&osvi, 0, sizeof(osvi));
216 osvi.dwOSVersionInfoSize = sizeof( osvi );
217 osvi.dwMajorVersion = wMajorVersion;
218 osvi.dwMinorVersion = wMinorVersion;
219 osvi.wServicePackMajor = wServicePackMajor;
220
221 return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
222}
223
224static hid_device *new_hid_device(void)
225{
226 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
227
228 if (dev == NULL) {
229 return NULL;
230 }
231
232 dev->device_handle = INVALID_HANDLE_VALUE;
233 dev->blocking = TRUE;
234 dev->output_report_length = 0;
235 dev->write_buf = NULL;
236 dev->input_report_length = 0;
237 dev->feature_report_length = 0;
238 dev->feature_buf = NULL;
239 dev->last_error_str = NULL;
240 dev->read_pending = FALSE;
241 dev->read_buf = NULL;
242 memset(&dev->ol, 0, sizeof(dev->ol));
243 dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
244 memset(&dev->write_ol, 0, sizeof(dev->write_ol));
245 dev->write_ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
246 dev->device_info = NULL;
247
248 return dev;
249}
250
251static void free_hid_device(hid_device *dev)
252{
253 CloseHandle(dev->ol.hEvent);
254 CloseHandle(dev->write_ol.hEvent);
255 CloseHandle(dev->device_handle);
256 free(dev->last_error_str);
257 dev->last_error_str = NULL;
258 free(dev->write_buf);
259 free(dev->feature_buf);
260 free(dev->read_buf);
261 hid_free_enumeration(dev->device_info);
262 free(dev);
263}
264
265static void register_winapi_error_to_buffer(wchar_t **error_buffer, const WCHAR *op)
266{
267 WCHAR system_err_buf[1024];
268 DWORD error_code = GetLastError();
269
270 free(*error_buffer);
271 *error_buffer = NULL;
272
273#ifdef HIDAPI_USING_SDL_RUNTIME
274 /* Thread-safe error handling */
275 SDL_ClearError();
276#endif
277
278 /* Only clear out error messages if NULL is passed into op */
279 if (!op) {
280 return;
281 }
282
283 DWORD system_err_len = FormatMessageW(
284 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
285 NULL,
286 error_code,
287 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
288 system_err_buf, ARRAYSIZE(system_err_buf),
289 NULL);
290
291 DWORD op_len = (DWORD)wcslen(op);
292
293 DWORD op_prefix_len =
294 op_len
295 + 15 /*: (0x00000000) */
296 ;
297 DWORD msg_len =
298 + op_prefix_len
299 + system_err_len
300 ;
301
302 WCHAR *msg = (WCHAR *)calloc(msg_len + 1, sizeof (WCHAR));
303
304 if (!msg)
305 return;
306
307 int printf_written = swprintf(msg, msg_len + 1, L"%.*ls: (0x%08X) %.*ls", (int)op_len, op, error_code, (int)system_err_len, system_err_buf);
308
309 if (printf_written < 0)
310 {
311 /* Highly unlikely */
312 msg[0] = L'\0';
313 return;
314 }
315
316 /* Get rid of the CR and LF that FormatMessage() sticks at the
317 end of the message. Thanks Microsoft! */
318 while(msg[msg_len-1] == L'\r' || msg[msg_len-1] == L'\n' || msg[msg_len-1] == L' ')
319 {
320 msg[msg_len-1] = L'\0';
321 msg_len--;
322 }
323
324#ifdef HIDAPI_USING_SDL_RUNTIME
325 /* Thread-safe error handling */
326 char *error_utf8 = SDL_iconv_wchar_utf8(msg);
327 if (error_utf8) {
328 SDL_SetError("%s", error_utf8);
329 SDL_free(error_utf8);
330 }
331 free(msg);
332#else
333 *error_buffer = msg;
334#endif
335}
336
337#if defined(__GNUC__) && (__GNUC__ + (__GNUC_MINOR__ >= 6) > 4)
338# pragma GCC diagnostic push
339# pragma GCC diagnostic ignored "-Warray-bounds"
340#endif
341/* A bug in GCC/mingw gives:
342 * error: array subscript 0 is outside array bounds of 'wchar_t *[0]' {aka 'short unsigned int *[]'} [-Werror=array-bounds]
343 * | free(*error_buffer);
344 * Which doesn't make sense in this context. */
345
346static void register_string_error_to_buffer(wchar_t **error_buffer, const WCHAR *string_error)
347{
348 free(*error_buffer);
349 *error_buffer = NULL;
350
351#ifdef HIDAPI_USING_SDL_RUNTIME
352 /* Thread-safe error handling */
353 char *error_utf8 = string_error ? SDL_iconv_wchar_utf8(string_error) : NULL;
354 if (error_utf8) {
355 SDL_SetError("%s", error_utf8);
356 SDL_free(error_utf8);
357 } else {
358 SDL_ClearError();
359 }
360#else
361 if (string_error) {
362 *error_buffer = _wcsdup(string_error);
363 }
364#endif /* HIDAPI_USING_SDL_RUNTIME */
365}
366
367#if defined(__GNUC__) && (__GNUC__ + (__GNUC_MINOR__ >= 6) > 4)
368# pragma GCC diagnostic pop
369#endif
370
371static void register_winapi_error(hid_device *dev, const WCHAR *op)
372{
373 register_winapi_error_to_buffer(&dev->last_error_str, op);
374}
375
376static void register_string_error(hid_device *dev, const WCHAR *string_error)
377{
378 register_string_error_to_buffer(&dev->last_error_str, string_error);
379}
380
381static wchar_t *last_global_error_str = NULL;
382
383static void register_global_winapi_error(const WCHAR *op)
384{
385 register_winapi_error_to_buffer(&last_global_error_str, op);
386}
387
388static void register_global_error(const WCHAR *string_error)
389{
390 register_string_error_to_buffer(&last_global_error_str, string_error);
391}
392
393static HANDLE open_device(const wchar_t *path, BOOL open_rw)
394{
395 HANDLE handle;
396 DWORD desired_access = (open_rw)? (GENERIC_WRITE | GENERIC_READ): 0;
397 DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
398
399 handle = CreateFileW(path,
400 desired_access,
401 share_mode,
402 NULL,
403 OPEN_EXISTING,
404 FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/
405 0);
406
407 return handle;
408}
409
410HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void)
411{
412 return &api_version;
413}
414
415HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
416{
417 return HID_API_VERSION_STR;
418}
419
420int HID_API_EXPORT hid_init(void)
421{
422 register_global_error(NULL);
423#ifndef HIDAPI_USE_DDK
424 if (!hidapi_initialized) {
425 if (lookup_functions() < 0) {
426 register_global_winapi_error(L"resolve DLL functions");
427 return -1;
428 }
429 hidapi_initialized = TRUE;
430 }
431#endif
432 return 0;
433}
434
435int HID_API_EXPORT hid_exit(void)
436{
437#ifndef HIDAPI_USE_DDK
438 free_library_handles();
439 hidapi_initialized = FALSE;
440#endif
441 register_global_error(NULL);
442 return 0;
443}
444
445static void* hid_internal_get_devnode_property(DEVINST dev_node, const DEVPROPKEY* property_key, DEVPROPTYPE expected_property_type)
446{
447 ULONG len = 0;
448 CONFIGRET cr;
449 DEVPROPTYPE property_type;
450 PBYTE property_value = NULL;
451
452 cr = CM_Get_DevNode_PropertyW(dev_node, property_key, &property_type, NULL, &len, 0);
453 if (cr != CR_BUFFER_SMALL || property_type != expected_property_type)
454 return NULL;
455
456 property_value = (PBYTE)calloc(len, sizeof(BYTE));
457 cr = CM_Get_DevNode_PropertyW(dev_node, property_key, &property_type, property_value, &len, 0);
458 if (cr != CR_SUCCESS) {
459 free(property_value);
460 return NULL;
461 }
462
463 return property_value;
464}
465
466static void* hid_internal_get_device_interface_property(const wchar_t* interface_path, const DEVPROPKEY* property_key, DEVPROPTYPE expected_property_type)
467{
468 ULONG len = 0;
469 CONFIGRET cr;
470 DEVPROPTYPE property_type;
471 PBYTE property_value = NULL;
472
473 cr = CM_Get_Device_Interface_PropertyW(interface_path, property_key, &property_type, NULL, &len, 0);
474 if (cr != CR_BUFFER_SMALL || property_type != expected_property_type)
475 return NULL;
476
477 property_value = (PBYTE)calloc(len, sizeof(BYTE));
478 cr = CM_Get_Device_Interface_PropertyW(interface_path, property_key, &property_type, property_value, &len, 0);
479 if (cr != CR_SUCCESS) {
480 free(property_value);
481 return NULL;
482 }
483
484 return property_value;
485}
486
487static void hid_internal_towupper(wchar_t* string)
488{
489 for (wchar_t* p = string; *p; ++p) *p = towupper(*p);
490}
491
492static int hid_internal_extract_int_token_value(wchar_t* string, const wchar_t* token)
493{
494 int token_value;
495 wchar_t* startptr, * endptr;
496
497 startptr = wcsstr(string, token);
498 if (!startptr)
499 return -1;
500
501 startptr += wcslen(token);
502 token_value = wcstol(startptr, &endptr, 16);
503 if (endptr == startptr)
504 return -1;
505
506 return token_value;
507}
508
509static void hid_internal_get_usb_info(struct hid_device_info* dev, DEVINST dev_node)
510{
511 wchar_t *device_id = NULL, *hardware_ids = NULL;
512
513 device_id = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
514 if (!device_id)
515 goto end;
516
517 /* Normalize to upper case */
518 hid_internal_towupper(device_id);
519
520 /* Check for Xbox Common Controller class (XUSB) device.
521 https://docs.microsoft.com/windows/win32/xinput/directinput-and-xusb-devices
522 https://docs.microsoft.com/windows/win32/xinput/xinput-and-directinput
523 */
524 if (hid_internal_extract_int_token_value(device_id, L"IG_") != -1) {
525 /* Get devnode parent to reach out USB device. */
526 if (CM_Get_Parent(&dev_node, dev_node, 0) != CR_SUCCESS)
527 goto end;
528 }
529
530 /* Get the hardware ids from devnode */
531 hardware_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_HardwareIds, DEVPROP_TYPE_STRING_LIST);
532 if (!hardware_ids)
533 goto end;
534
535 /* Get additional information from USB device's Hardware ID
536 https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers
537 https://docs.microsoft.com/windows-hardware/drivers/usbcon/enumeration-of-interfaces-not-grouped-in-collections
538 */
539 for (wchar_t* hardware_id = hardware_ids; *hardware_id; hardware_id += wcslen(hardware_id) + 1) {
540 /* Normalize to upper case */
541 hid_internal_towupper(hardware_id);
542
543 if (dev->release_number == 0) {
544 /* USB_DEVICE_DESCRIPTOR.bcdDevice value. */
545 int release_number = hid_internal_extract_int_token_value(hardware_id, L"REV_");
546 if (release_number != -1) {
547 dev->release_number = (unsigned short)release_number;
548 }
549 }
550
551 if (dev->interface_number == -1) {
552 /* USB_INTERFACE_DESCRIPTOR.bInterfaceNumber value. */
553 int interface_number = hid_internal_extract_int_token_value(hardware_id, L"MI_");
554 if (interface_number != -1) {
555 dev->interface_number = interface_number;
556 }
557 }
558 }
559
560 /* Try to get USB device manufacturer string if not provided by HidD_GetManufacturerString. */
561 if (wcslen(dev->manufacturer_string) == 0) {
562 wchar_t* manufacturer_string = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_Manufacturer, DEVPROP_TYPE_STRING);
563 if (manufacturer_string) {
564 free(dev->manufacturer_string);
565 dev->manufacturer_string = manufacturer_string;
566 }
567 }
568
569 /* Try to get USB device serial number if not provided by HidD_GetSerialNumberString. */
570 if (wcslen(dev->serial_number) == 0) {
571 DEVINST usb_dev_node = dev_node;
572 if (dev->interface_number != -1) {
573 /* Get devnode parent to reach out composite parent USB device.
574 https://docs.microsoft.com/windows-hardware/drivers/usbcon/enumeration-of-the-composite-parent-device
575 */
576 if (CM_Get_Parent(&usb_dev_node, dev_node, 0) != CR_SUCCESS)
577 goto end;
578 }
579
580 /* Get the device id of the USB device. */
581 free(device_id);
582 device_id = hid_internal_get_devnode_property(usb_dev_node, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
583 if (!device_id)
584 goto end;
585
586 /* Extract substring after last '\\' of Instance ID.
587 For USB devices it may contain device's serial number.
588 https://docs.microsoft.com/windows-hardware/drivers/install/instance-ids
589 */
590 for (wchar_t *ptr = device_id + wcslen(device_id); ptr > device_id; --ptr) {
591 /* Instance ID is unique only within the scope of the bus.
592 For USB devices it means that serial number is not available. Skip. */
593 if (*ptr == L'&')
594 break;
595
596 if (*ptr == L'\\') {
597 free(dev->serial_number);
598 dev->serial_number = _wcsdup(ptr + 1);
599 break;
600 }
601 }
602 }
603
604 /* If we can't get the interface number, it means that there is only one interface. */
605 if (dev->interface_number == -1)
606 dev->interface_number = 0;
607
608end:
609 free(device_id);
610 free(hardware_ids);
611}
612
613/* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices
614 Request this info via dev node properties instead.
615 https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html
616*/
617static void hid_internal_get_ble_info(struct hid_device_info* dev, DEVINST dev_node)
618{
619 if (wcslen(dev->manufacturer_string) == 0) {
620 /* Manufacturer Name String (UUID: 0x2A29) */
621 wchar_t* manufacturer_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_Manufacturer, DEVPROP_TYPE_STRING);
622 if (manufacturer_string) {
623 free(dev->manufacturer_string);
624 dev->manufacturer_string = manufacturer_string;
625 }
626 }
627
628 if (wcslen(dev->serial_number) == 0) {
629 /* Serial Number String (UUID: 0x2A25) */
630 wchar_t* serial_number = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_DeviceAddress, DEVPROP_TYPE_STRING);
631 if (serial_number) {
632 free(dev->serial_number);
633 dev->serial_number = serial_number;
634 }
635 }
636
637 if (wcslen(dev->product_string) == 0) {
638 /* Model Number String (UUID: 0x2A24) */
639 wchar_t* product_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_ModelNumber, DEVPROP_TYPE_STRING);
640 if (!product_string) {
641 DEVINST parent_dev_node = 0;
642 /* Fallback: Get devnode grandparent to reach out Bluetooth LE device node */
643 if (CM_Get_Parent(&parent_dev_node, dev_node, 0) == CR_SUCCESS) {
644 /* Device Name (UUID: 0x2A00) */
645 product_string = hid_internal_get_devnode_property(parent_dev_node, &DEVPKEY_NAME, DEVPROP_TYPE_STRING);
646 }
647 }
648
649 if (product_string) {
650 free(dev->product_string);
651 dev->product_string = product_string;
652 }
653 }
654}
655
656#ifdef HIDAPI_IGNORE_DEVICE
657static hid_bus_type get_bus_type(const wchar_t* interface_path)
658{
659 wchar_t *device_id = NULL, *compatible_ids = NULL;
660 CONFIGRET cr;
661 DEVINST dev_node;
662 hid_bus_type bus_type = HID_API_BUS_UNKNOWN;
663
664 /* Get the device id from interface path */
665 device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
666 if (!device_id)
667 goto end;
668
669 /* Open devnode from device id */
670 cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
671 if (cr != CR_SUCCESS)
672 goto end;
673
674 /* Get devnode parent */
675 cr = CM_Get_Parent(&dev_node, dev_node, 0);
676 if (cr != CR_SUCCESS)
677 goto end;
678
679 /* Get the compatible ids from parent devnode */
680 compatible_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_CompatibleIds, DEVPROP_TYPE_STRING_LIST);
681 if (!compatible_ids)
682 goto end;
683
684 /* Now we can parse parent's compatible IDs to find out the device bus type */
685 for (wchar_t* compatible_id = compatible_ids; *compatible_id; compatible_id += wcslen(compatible_id) + 1) {
686 /* Normalize to upper case */
687 hid_internal_towupper(compatible_id);
688
689 /* USB devices
690 https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support
691 https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers */
692 if (wcsstr(compatible_id, L"USB") != NULL) {
693 bus_type = HID_API_BUS_USB;
694 break;
695 }
696
697 /* Bluetooth devices
698 https://docs.microsoft.com/windows-hardware/drivers/bluetooth/installing-a-bluetooth-device */
699 if (wcsstr(compatible_id, L"BTHENUM") != NULL) {
700 bus_type = HID_API_BUS_BLUETOOTH;
701 break;
702 }
703
704 /* Bluetooth LE devices */
705 if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) {
706 bus_type = HID_API_BUS_BLUETOOTH;
707 break;
708 }
709
710 /* I2C devices
711 https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support-and-power-management */
712 if (wcsstr(compatible_id, L"PNP0C50") != NULL) {
713 bus_type = HID_API_BUS_I2C;
714 break;
715 }
716
717 /* SPI devices
718 https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-for-spi */
719 if (wcsstr(compatible_id, L"PNP0C51") != NULL) {
720 bus_type = HID_API_BUS_SPI;
721 break;
722 }
723 }
724end:
725 free(device_id);
726 free(compatible_ids);
727 return bus_type;
728}
729#endif /* HIDAPI_IGNORE_DEVICE */
730
731/* Unfortunately, HID_API_BUS_xxx constants alone aren't enough to distinguish between BLUETOOTH and BLE */
732
733#define HID_API_BUS_FLAG_BLE 0x01
734
735typedef struct hid_internal_detect_bus_type_result_ {
736 DEVINST dev_node;
737 hid_bus_type bus_type;
738 unsigned int bus_flags;
739} hid_internal_detect_bus_type_result;
740
741static hid_internal_detect_bus_type_result hid_internal_detect_bus_type(const wchar_t* interface_path)
742{
743 wchar_t *device_id = NULL, *compatible_ids = NULL;
744 CONFIGRET cr;
745 DEVINST dev_node;
746 hid_internal_detect_bus_type_result result = { 0 };
747
748 /* Get the device id from interface path */
749 device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
750 if (!device_id)
751 goto end;
752
753 /* Open devnode from device id */
754 cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
755 if (cr != CR_SUCCESS)
756 goto end;
757
758 /* Get devnode parent */
759 cr = CM_Get_Parent(&dev_node, dev_node, 0);
760 if (cr != CR_SUCCESS)
761 goto end;
762
763 /* Get the compatible ids from parent devnode */
764 compatible_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_CompatibleIds, DEVPROP_TYPE_STRING_LIST);
765 if (!compatible_ids)
766 goto end;
767
768 /* Now we can parse parent's compatible IDs to find out the device bus type */
769 for (wchar_t* compatible_id = compatible_ids; *compatible_id; compatible_id += wcslen(compatible_id) + 1) {
770 /* Normalize to upper case */
771 hid_internal_towupper(compatible_id);
772
773 /* USB devices
774 https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support
775 https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers */
776 if (wcsstr(compatible_id, L"USB") != NULL) {
777 result.bus_type = HID_API_BUS_USB;
778 break;
779 }
780
781 /* Bluetooth devices
782 https://docs.microsoft.com/windows-hardware/drivers/bluetooth/installing-a-bluetooth-device */
783 if (wcsstr(compatible_id, L"BTHENUM") != NULL) {
784 result.bus_type = HID_API_BUS_BLUETOOTH;
785 break;
786 }
787
788 /* Bluetooth LE devices */
789 if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) {
790 result.bus_type = HID_API_BUS_BLUETOOTH;
791 result.bus_flags |= HID_API_BUS_FLAG_BLE;
792 break;
793 }
794
795 /* I2C devices
796 https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support-and-power-management */
797 if (wcsstr(compatible_id, L"PNP0C50") != NULL) {
798 result.bus_type = HID_API_BUS_I2C;
799 break;
800 }
801
802 /* SPI devices
803 https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-for-spi */
804 if (wcsstr(compatible_id, L"PNP0C51") != NULL) {
805 result.bus_type = HID_API_BUS_SPI;
806 break;
807 }
808 }
809
810 result.dev_node = dev_node;
811
812end:
813 free(device_id);
814 free(compatible_ids);
815 return result;
816}
817
818static char *hid_internal_UTF16toUTF8(const wchar_t *src)
819{
820 char *dst = NULL;
821#ifdef HIDAPI_USING_SDL_RUNTIME
822 int len = WIN_WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL);
823#else
824 int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL);
825#endif
826 if (len) {
827 dst = (char*)calloc(len, sizeof(char));
828 if (dst == NULL) {
829 return NULL;
830 }
831#ifdef HIDAPI_USING_SDL_RUNTIME
832 WIN_WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, dst, len, NULL, NULL);
833#else
834 WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, dst, len, NULL, NULL);
835#endif
836 }
837
838 return dst;
839}
840
841static wchar_t *hid_internal_UTF8toUTF16(const char *src)
842{
843 wchar_t *dst = NULL;
844 int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, NULL, 0);
845 if (len) {
846 dst = (wchar_t*)calloc(len, sizeof(wchar_t));
847 if (dst == NULL) {
848 return NULL;
849 }
850 MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, dst, len);
851 }
852
853 return dst;
854}
855
856static struct hid_device_info *hid_internal_get_device_info(const wchar_t *path, HANDLE handle)
857{
858 struct hid_device_info *dev = NULL; /* return object */
859 HIDD_ATTRIBUTES attrib;
860 PHIDP_PREPARSED_DATA pp_data = NULL;
861 HIDP_CAPS caps;
862 wchar_t string[MAX_STRING_WCHARS + 1];
863 ULONG len;
864 ULONG size;
865 hid_internal_detect_bus_type_result detect_bus_type_result;
866
867 /* Create the record. */
868 dev = (struct hid_device_info*)calloc(1, sizeof(struct hid_device_info));
869
870 if (dev == NULL) {
871 return NULL;
872 }
873
874 /* Fill out the record */
875 dev->next = NULL;
876 dev->path = hid_internal_UTF16toUTF8(path);
877 dev->interface_number = -1;
878
879 attrib.Size = sizeof(HIDD_ATTRIBUTES);
880 if (HidD_GetAttributes(handle, &attrib)) {
881 /* VID/PID */
882 dev->vendor_id = attrib.VendorID;
883 dev->product_id = attrib.ProductID;
884
885 /* Release Number */
886 dev->release_number = attrib.VersionNumber;
887 }
888
889 /* Get the Usage Page and Usage for this device. */
890 if (HidD_GetPreparsedData(handle, &pp_data)) {
891 if (HidP_GetCaps(pp_data, &caps) == HIDP_STATUS_SUCCESS) {
892 dev->usage_page = caps.UsagePage;
893 dev->usage = caps.Usage;
894 }
895
896 HidD_FreePreparsedData(pp_data);
897 }
898
899 /* detect bus type before reading string descriptors */
900 detect_bus_type_result = hid_internal_detect_bus_type(path);
901 dev->bus_type = detect_bus_type_result.bus_type;
902
903 len = dev->bus_type == HID_API_BUS_USB ? MAX_STRING_WCHARS_USB : MAX_STRING_WCHARS;
904 string[len] = L'\0';
905 size = len * sizeof(wchar_t);
906
907 /* Serial Number */
908 string[0] = L'\0';
909 HidD_GetSerialNumberString(handle, string, size);
910 dev->serial_number = _wcsdup(string);
911
912 /* Manufacturer String */
913 string[0] = L'\0';
914 HidD_GetManufacturerString(handle, string, size);
915 dev->manufacturer_string = _wcsdup(string);
916
917 /* Product String */
918 string[0] = L'\0';
919 HidD_GetProductString(handle, string, size);
920 dev->product_string = _wcsdup(string);
921
922 /* now, the portion that depends on string descriptors */
923 switch (dev->bus_type) {
924 case HID_API_BUS_USB:
925 hid_internal_get_usb_info(dev, detect_bus_type_result.dev_node);
926 break;
927
928 case HID_API_BUS_BLUETOOTH:
929 if (detect_bus_type_result.bus_flags & HID_API_BUS_FLAG_BLE)
930 hid_internal_get_ble_info(dev, detect_bus_type_result.dev_node);
931 break;
932
933 case HID_API_BUS_UNKNOWN:
934 case HID_API_BUS_SPI:
935 case HID_API_BUS_I2C:
936 /* shut down -Wswitch */
937 break;
938 }
939
940 return dev;
941}
942
943static int hid_blacklist(unsigned short vendor_id, unsigned short product_id)
944{
945 size_t i;
946 static const struct { unsigned short vid; unsigned short pid; } known_bad[] = {
947 { 0x045E, 0x0822 }, /* Microsoft Precision Mouse - causes deadlock asking for device details */
948 { 0x0738, 0x2217 }, /* SPEEDLINK COMPETITION PRO - turns into an Android controller when enumerated */
949 { 0x0D8C, 0x0014 }, /* Sharkoon Skiller SGH2 headset - causes deadlock asking for device details */
950 { 0x1532, 0x0109 }, /* Razer Lycosa Gaming keyboard - causes deadlock asking for device details */
951 { 0x1532, 0x010B }, /* Razer Arctosa Gaming keyboard - causes deadlock asking for device details */
952 { 0x1B1C, 0x1B3D }, /* Corsair Gaming keyboard - causes deadlock asking for device details */
953 { 0x1CCF, 0x0000 } /* All Konami Amusement Devices - causes deadlock asking for device details */
954 };
955
956 for (i = 0; i < (sizeof(known_bad)/sizeof(known_bad[0])); i++) {
957 if ((vendor_id == known_bad[i].vid) && (product_id == known_bad[i].pid || known_bad[i].pid == 0x0000)) {
958 return 1;
959 }
960 }
961
962 return 0;
963}
964
965struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
966{
967 struct hid_device_info *root = NULL; /* return object */
968 struct hid_device_info *cur_dev = NULL;
969 GUID interface_class_guid;
970 CONFIGRET cr;
971 wchar_t* device_interface_list = NULL;
972 DWORD len;
973
974 if (hid_init() < 0) {
975 /* register_global_error: global error is reset by hid_init */
976 return NULL;
977 }
978
979 /* Retrieve HID Interface Class GUID
980 https://docs.microsoft.com/windows-hardware/drivers/install/guid-devinterface-hid */
981 HidD_GetHidGuid(&interface_class_guid);
982
983 /* Get the list of all device interfaces belonging to the HID class. */
984 /* Retry in case of list was changed between calls to
985 CM_Get_Device_Interface_List_SizeW and CM_Get_Device_Interface_ListW */
986 do {
987 cr = CM_Get_Device_Interface_List_SizeW(&len, &interface_class_guid, NULL, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
988 if (cr != CR_SUCCESS) {
989 register_global_error(L"Failed to get size of HID device interface list");
990 break;
991 }
992
993 if (device_interface_list != NULL) {
994 free(device_interface_list);
995 }
996
997 device_interface_list = (wchar_t*)calloc(len, sizeof(wchar_t));
998 if (device_interface_list == NULL) {
999 register_global_error(L"Failed to allocate memory for HID device interface list");
1000 return NULL;
1001 }
1002 cr = CM_Get_Device_Interface_ListW(&interface_class_guid, NULL, device_interface_list, len, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
1003 if (cr != CR_SUCCESS && cr != CR_BUFFER_SMALL) {
1004 register_global_error(L"Failed to get HID device interface list");
1005 }
1006 } while (cr == CR_BUFFER_SMALL);
1007
1008 if (cr != CR_SUCCESS) {
1009 goto end_of_function;
1010 }
1011
1012 /* Iterate over each device interface in the HID class, looking for the right one. */
1013 for (wchar_t* device_interface = device_interface_list; *device_interface; device_interface += wcslen(device_interface) + 1) {
1014 HANDLE device_handle = INVALID_HANDLE_VALUE;
1015 HIDD_ATTRIBUTES attrib;
1016
1017 /* XInput devices don't get real HID reports and are better handled by the raw input driver */
1018 if (wcsstr(device_interface, L"&IG_") != NULL) {
1019 continue;
1020 }
1021
1022 /* Open read-only handle to the device */
1023 device_handle = open_device(device_interface, FALSE);
1024
1025 /* Check validity of device_handle. */
1026 if (device_handle == INVALID_HANDLE_VALUE) {
1027 /* Unable to open the device. */
1028 continue;
1029 }
1030
1031 /* Get the Vendor ID and Product ID for this device. */
1032 attrib.Size = sizeof(HIDD_ATTRIBUTES);
1033 if (!HidD_GetAttributes(device_handle, &attrib)) {
1034 goto cont_close;
1035 }
1036
1037#ifdef HIDAPI_IGNORE_DEVICE
1038 /* See if there are any devices we should skip in enumeration */
1039 hid_bus_type bus_type = get_bus_type(device_interface);
1040 PHIDP_PREPARSED_DATA pp_data = NULL;
1041 HIDP_CAPS caps = { 0 };
1042 if (HidD_GetPreparsedData(device_handle, &pp_data)) {
1043 HidP_GetCaps(pp_data, &caps);
1044 HidD_FreePreparsedData(pp_data);
1045 }
1046 if (HIDAPI_IGNORE_DEVICE(bus_type, attrib.VendorID, attrib.ProductID, caps.UsagePage, caps.Usage)) {
1047 goto cont_close;
1048 }
1049#endif
1050
1051 /* Check the VID/PID to see if we should add this
1052 device to the enumeration list. */
1053 if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
1054 (product_id == 0x0 || attrib.ProductID == product_id) &&
1055 !hid_blacklist(attrib.VendorID, attrib.ProductID)) {
1056
1057 /* VID/PID match. Create the record. */
1058 struct hid_device_info *tmp = hid_internal_get_device_info(device_interface, device_handle);
1059
1060 if (tmp == NULL) {
1061 goto cont_close;
1062 }
1063
1064 if (cur_dev) {
1065 cur_dev->next = tmp;
1066 }
1067 else {
1068 root = tmp;
1069 }
1070 cur_dev = tmp;
1071 }
1072
1073cont_close:
1074 CloseHandle(device_handle);
1075 }
1076
1077 if (root == NULL) {
1078 if (vendor_id == 0 && product_id == 0) {
1079 register_global_error(L"No HID devices found in the system.");
1080 } else {
1081 register_global_error(L"No HID devices with requested VID/PID found in the system.");
1082 }
1083 }
1084
1085end_of_function:
1086 free(device_interface_list);
1087
1088 return root;
1089}
1090
1091void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
1092{
1093 /* TODO: Merge this with the Linux version. This function is platform-independent. */
1094 struct hid_device_info *d = devs;
1095 while (d) {
1096 struct hid_device_info *next = d->next;
1097 free(d->path);
1098 free(d->serial_number);
1099 free(d->manufacturer_string);
1100 free(d->product_string);
1101 free(d);
1102 d = next;
1103 }
1104}
1105
1106HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
1107{
1108 /* TODO: Merge this functions with the Linux version. This function should be platform independent. */
1109 struct hid_device_info *devs, *cur_dev;
1110 const char *path_to_open = NULL;
1111 hid_device *handle = NULL;
1112
1113 /* register_global_error: global error is reset by hid_enumerate/hid_init */
1114 devs = hid_enumerate(vendor_id, product_id);
1115 if (!devs) {
1116 /* register_global_error: global error is already set by hid_enumerate */
1117 return NULL;
1118 }
1119
1120 cur_dev = devs;
1121 while (cur_dev) {
1122 if (cur_dev->vendor_id == vendor_id &&
1123 cur_dev->product_id == product_id) {
1124 if (serial_number) {
1125 if (cur_dev->serial_number && wcscmp(serial_number, cur_dev->serial_number) == 0) {
1126 path_to_open = cur_dev->path;
1127 break;
1128 }
1129 }
1130 else {
1131 path_to_open = cur_dev->path;
1132 break;
1133 }
1134 }
1135 cur_dev = cur_dev->next;
1136 }
1137
1138 if (path_to_open) {
1139 /* Open the device */
1140 handle = hid_open_path(path_to_open);
1141 } else {
1142 register_global_error(L"Device with requested VID/PID/(SerialNumber) not found");
1143 }
1144
1145 hid_free_enumeration(devs);
1146
1147 return handle;
1148}
1149
1150HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
1151{
1152 hid_device *dev = NULL;
1153 wchar_t* interface_path = NULL;
1154 HANDLE device_handle = INVALID_HANDLE_VALUE;
1155 PHIDP_PREPARSED_DATA pp_data = NULL;
1156 HIDP_CAPS caps;
1157
1158 if (hid_init() < 0) {
1159 /* register_global_error: global error is reset by hid_init */
1160 goto end_of_function;
1161 }
1162
1163 interface_path = hid_internal_UTF8toUTF16(path);
1164 if (!interface_path) {
1165 register_global_error(L"Path conversion failure");
1166 goto end_of_function;
1167 }
1168
1169 /* Open a handle to the device */
1170 device_handle = open_device(interface_path, TRUE);
1171
1172 /* Check validity of write_handle. */
1173 if (device_handle == INVALID_HANDLE_VALUE) {
1174 /* System devices, such as keyboards and mice, cannot be opened in
1175 read-write mode, because the system takes exclusive control over
1176 them. This is to prevent keyloggers. However, feature reports
1177 can still be sent and received. Retry opening the device, but
1178 without read/write access. */
1179 device_handle = open_device(interface_path, FALSE);
1180
1181 /* Check the validity of the limited device_handle. */
1182 if (device_handle == INVALID_HANDLE_VALUE) {
1183 register_global_winapi_error(L"open_device");
1184 goto end_of_function;
1185 }
1186 }
1187
1188 /* Set the Input Report buffer size to 64 reports. */
1189 if (!HidD_SetNumInputBuffers(device_handle, 64)) {
1190 register_global_winapi_error(L"set input buffers");
1191 goto end_of_function;
1192 }
1193
1194 /* Get the Input Report length for the device. */
1195 if (!HidD_GetPreparsedData(device_handle, &pp_data)) {
1196 register_global_winapi_error(L"get preparsed data");
1197 goto end_of_function;
1198 }
1199
1200 if (HidP_GetCaps(pp_data, &caps) != HIDP_STATUS_SUCCESS) {
1201 register_global_error(L"HidP_GetCaps");
1202 goto end_of_function;
1203 }
1204
1205 dev = new_hid_device();
1206
1207 if (dev == NULL) {
1208 register_global_error(L"hid_device allocation error");
1209 goto end_of_function;
1210 }
1211
1212 dev->device_handle = device_handle;
1213 device_handle = INVALID_HANDLE_VALUE;
1214
1215 dev->output_report_length = caps.OutputReportByteLength;
1216 dev->input_report_length = caps.InputReportByteLength;
1217 dev->feature_report_length = caps.FeatureReportByteLength;
1218 dev->read_buf = (char*) malloc(dev->input_report_length);
1219 dev->device_info = hid_internal_get_device_info(interface_path, dev->device_handle);
1220
1221 /* On Windows 7, we need to use hid_write_output_report() over Bluetooth */
1222 if (dev->output_report_length > 512) {
1223 dev->use_hid_write_output_report = !IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN8 ), LOBYTE( _WIN32_WINNT_WIN8 ), 0 );
1224 }
1225
1226end_of_function:
1227 free(interface_path);
1228 CloseHandle(device_handle);
1229
1230 if (pp_data) {
1231 HidD_FreePreparsedData(pp_data);
1232 }
1233
1234 return dev;
1235}
1236
1237static int hid_write_output_report(hid_device *dev, const unsigned char *data, size_t length)
1238{
1239 BOOL res;
1240 res = HidD_SetOutputReport(dev->device_handle, (void *)data, (ULONG)length);
1241 if (res)
1242 return (int)length;
1243 else
1244 return -1;
1245}
1246
1247int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
1248{
1249 DWORD bytes_written = 0;
1250 int function_result = -1;
1251 BOOL res;
1252 BOOL overlapped = FALSE;
1253
1254 unsigned char *buf;
1255
1256 if (!data || !length) {
1257 register_string_error(dev, L"Zero buffer/length");
1258 return function_result;
1259 }
1260
1261 register_string_error(dev, NULL);
1262
1263 if (dev->use_hid_write_output_report) {
1264 return hid_write_output_report(dev, data, length);
1265 }
1266
1267 /* Make sure the right number of bytes are passed to WriteFile. Windows
1268 expects the number of bytes which are in the _longest_ report (plus
1269 one for the report number) bytes even if the data is a report
1270 which is shorter than that. Windows gives us this value in
1271 caps.OutputReportByteLength. If a user passes in fewer bytes than this,
1272 use cached temporary buffer which is the proper size. */
1273 if (length >= dev->output_report_length) {
1274 /* The user passed the right number of bytes. Use the buffer as-is. */
1275 buf = (unsigned char *) data;
1276 } else {
1277 if (dev->write_buf == NULL)
1278 dev->write_buf = (unsigned char *) malloc(dev->output_report_length);
1279 buf = dev->write_buf;
1280 memcpy(buf, data, length);
1281 memset(buf + length, 0, dev->output_report_length - length);
1282 length = dev->output_report_length;
1283 }
1284
1285 res = WriteFile(dev->device_handle, buf, (DWORD) length, &bytes_written, &dev->write_ol);
1286
1287 if (!res) {
1288 if (GetLastError() != ERROR_IO_PENDING) {
1289 /* WriteFile() failed. Return error. */
1290 register_winapi_error(dev, L"WriteFile");
1291 goto end_of_function;
1292 }
1293 overlapped = TRUE;
1294 } else {
1295 /* WriteFile() succeeded synchronously. */
1296 function_result = bytes_written;
1297 }
1298
1299 if (overlapped) {
1300 /* Wait for the transaction to complete. This makes
1301 hid_write() synchronous. */
1302 res = WaitForSingleObject(dev->write_ol.hEvent, 1000);
1303 if (res != WAIT_OBJECT_0) {
1304 /* There was a Timeout. */
1305 register_winapi_error(dev, L"hid_write/WaitForSingleObject");
1306 goto end_of_function;
1307 }
1308
1309 /* Get the result. */
1310 res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*wait*/);
1311 if (res) {
1312 function_result = bytes_written;
1313 }
1314 else {
1315 /* The Write operation failed. */
1316 register_winapi_error(dev, L"hid_write/GetOverlappedResult");
1317 goto end_of_function;
1318 }
1319 }
1320
1321end_of_function:
1322 return function_result;
1323}
1324
1325
1326int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1327{
1328 DWORD bytes_read = 0;
1329 size_t copy_len = 0;
1330 BOOL res = FALSE;
1331 BOOL overlapped = FALSE;
1332
1333 if (!data || !length) {
1334 register_string_error(dev, L"Zero buffer/length");
1335 return -1;
1336 }
1337
1338 register_string_error(dev, NULL);
1339
1340 /* Copy the handle for convenience. */
1341 HANDLE ev = dev->ol.hEvent;
1342
1343 if (!dev->read_pending) {
1344 /* Start an Overlapped I/O read. */
1345 dev->read_pending = TRUE;
1346 memset(dev->read_buf, 0, dev->input_report_length);
1347 ResetEvent(ev);
1348 res = ReadFile(dev->device_handle, dev->read_buf, (DWORD) dev->input_report_length, &bytes_read, &dev->ol);
1349
1350 if (!res) {
1351 if (GetLastError() != ERROR_IO_PENDING) {
1352 /* ReadFile() has failed.
1353 Clean up and return error. */
1354 register_winapi_error(dev, L"ReadFile");
1355 CancelIo(dev->device_handle);
1356 dev->read_pending = FALSE;
1357 goto end_of_function;
1358 }
1359 overlapped = TRUE;
1360 }
1361 }
1362 else {
1363 overlapped = TRUE;
1364 }
1365
1366 if (overlapped) {
1367 /* See if there is any data yet. */
1368 res = WaitForSingleObject(ev, milliseconds >= 0 ? (DWORD)milliseconds : INFINITE);
1369 if (res != WAIT_OBJECT_0) {
1370 /* There was no data this time. Return zero bytes available,
1371 but leave the Overlapped I/O running. */
1372 return 0;
1373 }
1374
1375 /* Get the number of bytes read. The actual data has been copied to the data[]
1376 array which was passed to ReadFile(). We must not wait here because we've
1377 already waited on our event above, and since it's auto-reset, it will have
1378 been reset back to unsignalled by now. */
1379 res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, FALSE/*don't wait now - already did on the prev step*/);
1380 }
1381 /* Set pending back to false, even if GetOverlappedResult() returned error. */
1382 dev->read_pending = FALSE;
1383
1384 if (res && bytes_read > 0) {
1385 if (dev->read_buf[0] == 0x0) {
1386 /* If report numbers aren't being used, but Windows sticks a report
1387 number (0x0) on the beginning of the report anyway. To make this
1388 work like the other platforms, and to make it work more like the
1389 HID spec, we'll skip over this byte. */
1390 bytes_read--;
1391 copy_len = length > bytes_read ? bytes_read : length;
1392 memcpy(data, dev->read_buf+1, copy_len);
1393 }
1394 else {
1395 /* Copy the whole buffer, report number and all. */
1396 copy_len = length > bytes_read ? bytes_read : length;
1397 memcpy(data, dev->read_buf, copy_len);
1398 }
1399 }
1400 if (!res) {
1401 register_winapi_error(dev, L"hid_read_timeout/GetOverlappedResult");
1402 }
1403
1404end_of_function:
1405 if (!res) {
1406 return -1;
1407 }
1408
1409 return (int) copy_len;
1410}
1411
1412int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
1413{
1414 return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
1415}
1416
1417int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
1418{
1419 dev->blocking = !nonblock;
1420 return 0; /* Success */
1421}
1422
1423int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
1424{
1425 BOOL res = FALSE;
1426 unsigned char *buf;
1427 size_t length_to_send;
1428
1429 if (!data || !length) {
1430 register_string_error(dev, L"Zero buffer/length");
1431 return -1;
1432 }
1433
1434 register_string_error(dev, NULL);
1435
1436 /* Windows expects at least caps.FeatureReportByteLength bytes passed
1437 to HidD_SetFeature(), even if the report is shorter. Any less sent and
1438 the function fails with error ERROR_INVALID_PARAMETER set. Any more
1439 and HidD_SetFeature() silently truncates the data sent in the report
1440 to caps.FeatureReportByteLength. */
1441 if (length >= dev->feature_report_length) {
1442 buf = (unsigned char *) data;
1443 length_to_send = length;
1444 } else {
1445 if (dev->feature_buf == NULL)
1446 dev->feature_buf = (unsigned char *) malloc(dev->feature_report_length);
1447 buf = dev->feature_buf;
1448 memcpy(buf, data, length);
1449 memset(buf + length, 0, dev->feature_report_length - length);
1450 length_to_send = dev->feature_report_length;
1451 }
1452
1453 res = HidD_SetFeature(dev->device_handle, (PVOID)buf, (DWORD) length_to_send);
1454
1455 if (!res) {
1456 register_winapi_error(dev, L"HidD_SetFeature");
1457 return -1;
1458 }
1459
1460 return (int) length;
1461}
1462
1463static int hid_get_report(hid_device *dev, DWORD report_type, unsigned char *data, size_t length)
1464{
1465 BOOL res;
1466 DWORD bytes_returned = 0;
1467
1468 OVERLAPPED ol;
1469 memset(&ol, 0, sizeof(ol));
1470
1471 if (!data || !length) {
1472 register_string_error(dev, L"Zero buffer/length");
1473 return -1;
1474 }
1475
1476 register_string_error(dev, NULL);
1477
1478 res = DeviceIoControl(dev->device_handle,
1479 report_type,
1480 data, (DWORD) length,
1481 data, (DWORD) length,
1482 &bytes_returned, &ol);
1483
1484 if (!res) {
1485 if (GetLastError() != ERROR_IO_PENDING) {
1486 /* DeviceIoControl() failed. Return error. */
1487 register_winapi_error(dev, L"Get Input/Feature Report DeviceIoControl");
1488 return -1;
1489 }
1490 }
1491
1492 /* Wait here until the write is done. This makes
1493 hid_get_feature_report() synchronous. */
1494 res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
1495 if (!res) {
1496 /* The operation failed. */
1497 register_winapi_error(dev, L"Get Input/Feature Report GetOverLappedResult");
1498 return -1;
1499 }
1500
1501 /* When numbered reports aren't used,
1502 bytes_returned seem to include only what is actually received from the device
1503 (not including the first byte with 0, as an indication "no numbered reports"). */
1504 if (data[0] == 0x0) {
1505 bytes_returned++;
1506 }
1507
1508 return bytes_returned;
1509}
1510
1511int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
1512{
1513 /* We could use HidD_GetFeature() instead, but it doesn't give us an actual length, unfortunately */
1514 return hid_get_report(dev, IOCTL_HID_GET_FEATURE, data, length);
1515}
1516
1517int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
1518{
1519 /* We could use HidD_GetInputReport() instead, but it doesn't give us an actual length, unfortunately */
1520 return hid_get_report(dev, IOCTL_HID_GET_INPUT_REPORT, data, length);
1521}
1522
1523#if defined(__GNUC__) && __GNUC__ >= 8
1524# pragma GCC diagnostic push
1525# pragma GCC diagnostic ignored "-Wcast-function-type"
1526#endif
1527void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
1528{
1529 typedef BOOL (WINAPI *CancelIoEx_t)(HANDLE hFile, LPOVERLAPPED lpOverlapped);
1530 CancelIoEx_t CancelIoExFunc = (CancelIoEx_t)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CancelIoEx");
1531
1532 if (!dev)
1533 return;
1534
1535 if (CancelIoExFunc) {
1536 CancelIoExFunc(dev->device_handle, NULL);
1537 } else {
1538 /* Windows XP, this will only cancel I/O on the current thread */
1539 CancelIo(dev->device_handle);
1540 }
1541 if (dev->read_pending) {
1542 DWORD bytes_read = 0;
1543 GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
1544 }
1545 free_hid_device(dev);
1546}
1547#if defined(__GNUC__) && __GNUC__ >= 8
1548# pragma GCC diagnostic pop
1549#endif
1550
1551int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
1552{
1553 if (!string || !maxlen) {
1554 register_string_error(dev, L"Zero buffer/length");
1555 return -1;
1556 }
1557
1558 if (!dev->device_info) {
1559 register_string_error(dev, L"NULL device info");
1560 return -1;
1561 }
1562
1563 wcsncpy(string, dev->device_info->manufacturer_string, maxlen);
1564 string[maxlen - 1] = L'\0';
1565
1566 register_string_error(dev, NULL);
1567
1568 return 0;
1569}
1570
1571int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
1572{
1573 if (!string || !maxlen) {
1574 register_string_error(dev, L"Zero buffer/length");
1575 return -1;
1576 }
1577
1578 if (!dev->device_info) {
1579 register_string_error(dev, L"NULL device info");
1580 return -1;
1581 }
1582
1583 wcsncpy(string, dev->device_info->product_string, maxlen);
1584 string[maxlen - 1] = L'\0';
1585
1586 register_string_error(dev, NULL);
1587
1588 return 0;
1589}
1590
1591int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1592{
1593 if (!string || !maxlen) {
1594 register_string_error(dev, L"Zero buffer/length");
1595 return -1;
1596 }
1597
1598 if (!dev->device_info) {
1599 register_string_error(dev, L"NULL device info");
1600 return -1;
1601 }
1602
1603 wcsncpy(string, dev->device_info->serial_number, maxlen);
1604 string[maxlen - 1] = L'\0';
1605
1606 register_string_error(dev, NULL);
1607
1608 return 0;
1609}
1610
1611HID_API_EXPORT struct hid_device_info * HID_API_CALL hid_get_device_info(hid_device *dev) {
1612 if (!dev->device_info)
1613 {
1614 register_string_error(dev, L"NULL device info");
1615 return NULL;
1616 }
1617
1618 return dev->device_info;
1619}
1620
1621int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1622{
1623 BOOL res;
1624
1625 if (dev->device_info && dev->device_info->bus_type == HID_API_BUS_USB && maxlen > MAX_STRING_WCHARS_USB) {
1626 string[MAX_STRING_WCHARS_USB] = L'\0';
1627 maxlen = MAX_STRING_WCHARS_USB;
1628 }
1629
1630 res = HidD_GetIndexedString(dev->device_handle, string_index, string, (ULONG)maxlen * sizeof(wchar_t));
1631 if (!res) {
1632 register_winapi_error(dev, L"HidD_GetIndexedString");
1633 return -1;
1634 }
1635
1636 register_string_error(dev, NULL);
1637
1638 return 0;
1639}
1640
1641int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id)
1642{
1643 wchar_t *interface_path = NULL, *device_id = NULL;
1644 CONFIGRET cr = CR_FAILURE;
1645 DEVINST dev_node;
1646 DEVPROPTYPE property_type;
1647 ULONG len;
1648
1649 if (!container_id) {
1650 register_string_error(dev, L"Invalid Container ID");
1651 return -1;
1652 }
1653
1654 register_string_error(dev, NULL);
1655
1656 interface_path = hid_internal_UTF8toUTF16(dev->device_info->path);
1657 if (!interface_path) {
1658 register_string_error(dev, L"Path conversion failure");
1659 goto end;
1660 }
1661
1662 /* Get the device id from interface path */
1663 device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
1664 if (!device_id) {
1665 register_string_error(dev, L"Failed to get device interface property InstanceId");
1666 goto end;
1667 }
1668
1669 /* Open devnode from device id */
1670 cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
1671 if (cr != CR_SUCCESS) {
1672 register_string_error(dev, L"Failed to locate device node");
1673 goto end;
1674 }
1675
1676 /* Get the container id from devnode */
1677 len = sizeof(*container_id);
1678 cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_ContainerId, &property_type, (PBYTE)container_id, &len, 0);
1679 if (cr == CR_SUCCESS && property_type != DEVPROP_TYPE_GUID)
1680 cr = CR_FAILURE;
1681
1682 if (cr != CR_SUCCESS)
1683 register_string_error(dev, L"Failed to read ContainerId property from device node");
1684
1685end:
1686 free(interface_path);
1687 free(device_id);
1688
1689 return cr == CR_SUCCESS ? 0 : -1;
1690}
1691
1692
1693int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
1694{
1695 PHIDP_PREPARSED_DATA pp_data = NULL;
1696
1697 if (!HidD_GetPreparsedData(dev->device_handle, &pp_data) || pp_data == NULL) {
1698 register_string_error(dev, L"HidD_GetPreparsedData");
1699 return -1;
1700 }
1701
1702 int res = hid_winapi_descriptor_reconstruct_pp_data(pp_data, buf, buf_size);
1703
1704 HidD_FreePreparsedData(pp_data);
1705
1706 return res;
1707}
1708
1709HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
1710{
1711 if (dev) {
1712 if (dev->last_error_str == NULL)
1713 return L"Success";
1714 return (wchar_t*)dev->last_error_str;
1715 }
1716
1717 if (last_global_error_str == NULL)
1718 return L"Success";
1719 return last_global_error_str;
1720}
1721
1722#ifndef hidapi_winapi_EXPORTS
1723#include "hidapi_descriptor_reconstruct.c"
1724#endif
1725
1726#ifdef __cplusplus
1727} /* extern "C" */
1728#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.rc b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.rc
new file mode 100644
index 0000000..530917e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.rc
@@ -0,0 +1,35 @@
1#include "winresrc.h"
2
3#include "hidapi.h"
4
5// English
6LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
7VS_VERSION_INFO VERSIONINFO
8 FILEVERSION HID_API_VERSION_MAJOR,HID_API_VERSION_MINOR,HID_API_VERSION_PATCH,0
9 PRODUCTVERSION HID_API_VERSION_MAJOR,HID_API_VERSION_MINOR,HID_API_VERSION_PATCH,0
10 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
11 FILEFLAGS 0
12#ifdef _DEBUG
13 | VS_FF_DEBUG
14#endif
15 FILEOS VOS_NT_WINDOWS32
16 FILETYPE VFT_DLL
17BEGIN
18 BLOCK "StringFileInfo"
19 BEGIN
20 BLOCK "04090000"
21 BEGIN
22 VALUE "CompanyName", "libusb/hidapi Team"
23 VALUE "FileDescription", "A multi-platform library to interface with HID devices (USB, Bluetooth, etc.)"
24 VALUE "FileVersion", HID_API_VERSION_STR
25 VALUE "ProductName", "HIDAPI"
26 VALUE "ProductVersion", HID_API_VERSION_STR
27 VALUE "Licence", "https://github.com/libusb/hidapi/blob/master/LICENSE.txt"
28 VALUE "Comments", "https://github.com/libusb/hidapi"
29 END
30 END
31 BLOCK "VarFileInfo"
32 BEGIN
33 VALUE "Translation", 0x409, 0
34 END
35END
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.sln b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.sln
new file mode 100644
index 0000000..aeb2660
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.sln
@@ -0,0 +1,41 @@
1
2Microsoft Visual Studio Solution File, Format Version 12.00
3# Visual Studio 15
4VisualStudioVersion = 15.0.28307.136
5MinimumVisualStudioVersion = 10.0.40219.1
6Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hidapi", "hidapi.vcxproj", "{A107C21C-418A-4697-BB10-20C3AA60E2E4}"
7EndProject
8Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hidtest", "hidtest.vcxproj", "{23E9FF6A-49D1-4993-B2B5-BBB992C6C712}"
9EndProject
10Global
11 GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 Debug|Win32 = Debug|Win32
13 Debug|x64 = Debug|x64
14 Release|Win32 = Release|Win32
15 Release|x64 = Release|x64
16 EndGlobalSection
17 GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Debug|Win32.ActiveCfg = Debug|Win32
19 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Debug|Win32.Build.0 = Debug|Win32
20 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Debug|x64.ActiveCfg = Debug|x64
21 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Debug|x64.Build.0 = Debug|x64
22 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Release|Win32.ActiveCfg = Release|Win32
23 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Release|Win32.Build.0 = Release|Win32
24 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Release|x64.ActiveCfg = Release|x64
25 {A107C21C-418A-4697-BB10-20C3AA60E2E4}.Release|x64.Build.0 = Release|x64
26 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Debug|Win32.ActiveCfg = Debug|Win32
27 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Debug|Win32.Build.0 = Debug|Win32
28 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Debug|x64.ActiveCfg = Debug|x64
29 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Debug|x64.Build.0 = Debug|x64
30 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Release|Win32.ActiveCfg = Release|Win32
31 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Release|Win32.Build.0 = Release|Win32
32 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Release|x64.ActiveCfg = Release|x64
33 {23E9FF6A-49D1-4993-B2B5-BBB992C6C712}.Release|x64.Build.0 = Release|x64
34 EndGlobalSection
35 GlobalSection(SolutionProperties) = preSolution
36 HideSolutionNode = FALSE
37 EndGlobalSection
38 GlobalSection(ExtensibilityGlobals) = postSolution
39 SolutionGuid = {8749E535-9C65-4A89-840E-78D7578C7866}
40 EndGlobalSection
41EndGlobal
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcproj b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcproj
new file mode 100644
index 0000000..e331064
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcproj
@@ -0,0 +1,200 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="9.00"
5 Name="hidapi"
6 ProjectGUID="{A107C21C-418A-4697-BB10-20C3AA60E2E4}"
7 RootNamespace="hidapi"
8 Keyword="Win32Proj"
9 TargetFrameworkVersion="196613"
10 >
11 <Platforms>
12 <Platform
13 Name="Win32"
14 />
15 </Platforms>
16 <ToolFiles>
17 </ToolFiles>
18 <Configurations>
19 <Configuration
20 Name="Debug|Win32"
21 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
22 IntermediateDirectory="$(ConfigurationName)"
23 ConfigurationType="2"
24 CharacterSet="1"
25 >
26 <Tool
27 Name="VCPreBuildEventTool"
28 />
29 <Tool
30 Name="VCCustomBuildTool"
31 />
32 <Tool
33 Name="VCXMLDataGeneratorTool"
34 />
35 <Tool
36 Name="VCWebServiceProxyGeneratorTool"
37 />
38 <Tool
39 Name="VCMIDLTool"
40 />
41 <Tool
42 Name="VCCLCompilerTool"
43 Optimization="0"
44 AdditionalIncludeDirectories="..\hidapi"
45 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;HIDAPI_EXPORTS"
46 MinimalRebuild="true"
47 BasicRuntimeChecks="3"
48 RuntimeLibrary="3"
49 UsePrecompiledHeader="0"
50 WarningLevel="3"
51 DebugInformationFormat="4"
52 />
53 <Tool
54 Name="VCManagedResourceCompilerTool"
55 />
56 <Tool
57 Name="VCResourceCompilerTool"
58 />
59 <Tool
60 Name="VCPreLinkEventTool"
61 />
62 <Tool
63 Name="VCLinkerTool"
64 LinkIncremental="2"
65 GenerateDebugInformation="true"
66 SubSystem="2"
67 TargetMachine="1"
68 />
69 <Tool
70 Name="VCALinkTool"
71 />
72 <Tool
73 Name="VCManifestTool"
74 />
75 <Tool
76 Name="VCXDCMakeTool"
77 />
78 <Tool
79 Name="VCBscMakeTool"
80 />
81 <Tool
82 Name="VCFxCopTool"
83 />
84 <Tool
85 Name="VCAppVerifierTool"
86 />
87 <Tool
88 Name="VCPostBuildEventTool"
89 />
90 </Configuration>
91 <Configuration
92 Name="Release|Win32"
93 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
94 IntermediateDirectory="$(ConfigurationName)"
95 ConfigurationType="2"
96 CharacterSet="1"
97 WholeProgramOptimization="1"
98 >
99 <Tool
100 Name="VCPreBuildEventTool"
101 />
102 <Tool
103 Name="VCCustomBuildTool"
104 />
105 <Tool
106 Name="VCXMLDataGeneratorTool"
107 />
108 <Tool
109 Name="VCWebServiceProxyGeneratorTool"
110 />
111 <Tool
112 Name="VCMIDLTool"
113 />
114 <Tool
115 Name="VCCLCompilerTool"
116 Optimization="2"
117 EnableIntrinsicFunctions="true"
118 AdditionalIncludeDirectories="..\hidapi"
119 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;HIDAPI_EXPORTS"
120 RuntimeLibrary="2"
121 EnableFunctionLevelLinking="true"
122 UsePrecompiledHeader="0"
123 WarningLevel="3"
124 DebugInformationFormat="3"
125 />
126 <Tool
127 Name="VCManagedResourceCompilerTool"
128 />
129 <Tool
130 Name="VCResourceCompilerTool"
131 />
132 <Tool
133 Name="VCPreLinkEventTool"
134 />
135 <Tool
136 Name="VCLinkerTool"
137 AdditionalDependencies="setupapi.lib"
138 LinkIncremental="1"
139 GenerateDebugInformation="true"
140 SubSystem="2"
141 OptimizeReferences="2"
142 EnableCOMDATFolding="2"
143 TargetMachine="1"
144 />
145 <Tool
146 Name="VCALinkTool"
147 />
148 <Tool
149 Name="VCManifestTool"
150 />
151 <Tool
152 Name="VCXDCMakeTool"
153 />
154 <Tool
155 Name="VCBscMakeTool"
156 />
157 <Tool
158 Name="VCFxCopTool"
159 />
160 <Tool
161 Name="VCAppVerifierTool"
162 />
163 <Tool
164 Name="VCPostBuildEventTool"
165 />
166 </Configuration>
167 </Configurations>
168 <References>
169 </References>
170 <Files>
171 <Filter
172 Name="Source Files"
173 Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
174 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
175 >
176 <File
177 RelativePath=".\hid.c"
178 >
179 </File>
180 </Filter>
181 <Filter
182 Name="Header Files"
183 Filter="h;hpp;hxx;hm;inl;inc;xsd"
184 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
185 >
186 <File
187 RelativePath="..\hidapi\hidapi.h"
188 >
189 </File>
190 </Filter>
191 <Filter
192 Name="Resource Files"
193 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
194 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
195 >
196 </Filter>
197 </Files>
198 <Globals>
199 </Globals>
200</VisualStudioProject>
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcxproj b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcxproj
new file mode 100644
index 0000000..7f7a95d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi.vcxproj
@@ -0,0 +1,200 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <ItemGroup Label="ProjectConfigurations">
4 <ProjectConfiguration Include="Debug|Win32">
5 <Configuration>Debug</Configuration>
6 <Platform>Win32</Platform>
7 </ProjectConfiguration>
8 <ProjectConfiguration Include="Debug|x64">
9 <Configuration>Debug</Configuration>
10 <Platform>x64</Platform>
11 </ProjectConfiguration>
12 <ProjectConfiguration Include="Release|Win32">
13 <Configuration>Release</Configuration>
14 <Platform>Win32</Platform>
15 </ProjectConfiguration>
16 <ProjectConfiguration Include="Release|x64">
17 <Configuration>Release</Configuration>
18 <Platform>x64</Platform>
19 </ProjectConfiguration>
20 </ItemGroup>
21 <PropertyGroup Label="Globals">
22 <ProjectGuid>{A107C21C-418A-4697-BB10-20C3AA60E2E4}</ProjectGuid>
23 <RootNamespace>hidapi</RootNamespace>
24 <Keyword>Win32Proj</Keyword>
25 </PropertyGroup>
26 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
27 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
28 <ConfigurationType>DynamicLibrary</ConfigurationType>
29 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
30 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
31 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
32 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
33 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
34 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
35 <CharacterSet>Unicode</CharacterSet>
36 <WholeProgramOptimization>true</WholeProgramOptimization>
37 </PropertyGroup>
38 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
39 <ConfigurationType>DynamicLibrary</ConfigurationType>
40 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
41 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
42 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
43 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
44 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
45 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
46 <CharacterSet>Unicode</CharacterSet>
47 <WholeProgramOptimization>true</WholeProgramOptimization>
48 </PropertyGroup>
49 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
50 <ConfigurationType>DynamicLibrary</ConfigurationType>
51 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
52 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
53 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
54 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
55 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
56 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
57 <CharacterSet>Unicode</CharacterSet>
58 </PropertyGroup>
59 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
60 <ConfigurationType>DynamicLibrary</ConfigurationType>
61 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
62 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
63 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
64 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
65 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
66 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
67 <CharacterSet>Unicode</CharacterSet>
68 </PropertyGroup>
69 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
70 <ImportGroup Label="ExtensionSettings">
71 </ImportGroup>
72 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
73 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
74 </ImportGroup>
75 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
76 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
77 </ImportGroup>
78 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
79 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
80 </ImportGroup>
81 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
82 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
83 </ImportGroup>
84 <PropertyGroup Label="UserMacros" />
85 <PropertyGroup>
86 <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
87 </PropertyGroup>
88 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
89 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
90 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
91 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
92 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
93 <ClCompile>
94 <Optimization>Disabled</Optimization>
95 <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
96 <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HIDAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
97 <MinimalRebuild>true</MinimalRebuild>
98 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
99 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
100 <PrecompiledHeader />
101 <WarningLevel>Level3</WarningLevel>
102 <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
103 </ClCompile>
104 <Link>
105 <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
106 <GenerateDebugInformation>true</GenerateDebugInformation>
107 <SubSystem>Windows</SubSystem>
108 <TargetMachine>MachineX86</TargetMachine>
109 </Link>
110 <ResourceCompile>
111 <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
112 <PreprocessorDefinitions>_DEBUG</PreprocessorDefinitions>
113 </ResourceCompile>
114 </ItemDefinitionGroup>
115 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
116 <ClCompile>
117 <Optimization>Disabled</Optimization>
118 <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
119 <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HIDAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
120 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
121 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
122 <PrecompiledHeader>
123 </PrecompiledHeader>
124 <WarningLevel>Level3</WarningLevel>
125 <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
126 </ClCompile>
127 <Link>
128 <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
129 <GenerateDebugInformation>true</GenerateDebugInformation>
130 <SubSystem>Windows</SubSystem>
131 </Link>
132 <ResourceCompile>
133 <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
134 <PreprocessorDefinitions>_DEBUG</PreprocessorDefinitions>
135 </ResourceCompile>
136 </ItemDefinitionGroup>
137 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
138 <ClCompile>
139 <Optimization>MaxSpeed</Optimization>
140 <IntrinsicFunctions>true</IntrinsicFunctions>
141 <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
142 <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HIDAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
143 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
144 <FunctionLevelLinking>true</FunctionLevelLinking>
145 <PrecompiledHeader />
146 <WarningLevel>Level3</WarningLevel>
147 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
148 </ClCompile>
149 <Link>
150 <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
151 <GenerateDebugInformation>true</GenerateDebugInformation>
152 <SubSystem>Windows</SubSystem>
153 <OptimizeReferences>true</OptimizeReferences>
154 <EnableCOMDATFolding>true</EnableCOMDATFolding>
155 <TargetMachine>MachineX86</TargetMachine>
156 </Link>
157 <ResourceCompile>
158 <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
159 <PreprocessorDefinitions>NDEBUG</PreprocessorDefinitions>
160 </ResourceCompile>
161 </ItemDefinitionGroup>
162 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
163 <ClCompile>
164 <Optimization>MaxSpeed</Optimization>
165 <IntrinsicFunctions>true</IntrinsicFunctions>
166 <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
167 <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HIDAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
168 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
169 <FunctionLevelLinking>true</FunctionLevelLinking>
170 <PrecompiledHeader>
171 </PrecompiledHeader>
172 <WarningLevel>Level3</WarningLevel>
173 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
174 </ClCompile>
175 <Link>
176 <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
177 <GenerateDebugInformation>true</GenerateDebugInformation>
178 <SubSystem>Windows</SubSystem>
179 <OptimizeReferences>true</OptimizeReferences>
180 <EnableCOMDATFolding>true</EnableCOMDATFolding>
181 </Link>
182 <ResourceCompile>
183 <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
184 <PreprocessorDefinitions>NDEBUG</PreprocessorDefinitions>
185 </ResourceCompile>
186 </ItemDefinitionGroup>
187 <ItemGroup>
188 <ClCompile Include="hid.c" />
189 </ItemGroup>
190 <ItemGroup>
191 <ClInclude Include="..\hidapi\hidapi.h" />
192 <ClInclude Include="hidapi_winapi.h" />
193 </ItemGroup>
194 <ItemGroup>
195 <ResourceCompile Include="hidapi.rc" />
196 </ItemGroup>
197 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
198 <ImportGroup Label="ExtensionTargets">
199 </ImportGroup>
200</Project> \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_cfgmgr32.h b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_cfgmgr32.h
new file mode 100644
index 0000000..09bf4d7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_cfgmgr32.h
@@ -0,0 +1,86 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19
20#ifndef HIDAPI_CFGMGR32_H
21#define HIDAPI_CFGMGR32_H
22
23#ifdef HIDAPI_USE_DDK
24
25#include <cfgmgr32.h>
26#include <initguid.h>
27#include <devpkey.h>
28#include <propkey.h>
29
30#else
31
32/* This part of the header mimics cfgmgr32.h,
33 but only what is used by HIDAPI */
34
35//#include <initguid.h>
36#include <devpropdef.h>
37//#include <propkeydef.h>
38
39#ifndef PROPERTYKEY_DEFINED
40#define PROPERTYKEY_DEFINED
41
42typedef struct
43{
44 GUID fmtid;
45 DWORD pid;
46} PROPERTYKEY;
47
48#endif /* PROPERTYKEY_DEFINED */
49
50typedef DWORD RETURN_TYPE;
51typedef RETURN_TYPE CONFIGRET;
52typedef DWORD DEVNODE, DEVINST;
53typedef DEVNODE* PDEVNODE, * PDEVINST;
54typedef WCHAR* DEVNODEID_W, * DEVINSTID_W;
55
56#define CR_SUCCESS (0x00000000)
57#define CR_BUFFER_SMALL (0x0000001A)
58#define CR_FAILURE (0x00000013)
59
60#define CM_LOCATE_DEVNODE_NORMAL 0x00000000
61
62#define CM_GET_DEVICE_INTERFACE_LIST_PRESENT (0x00000000)
63
64typedef CONFIGRET(__stdcall* CM_Locate_DevNodeW_)(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags);
65typedef CONFIGRET(__stdcall* CM_Get_Parent_)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
66typedef CONFIGRET(__stdcall* CM_Get_DevNode_PropertyW_)(DEVINST dnDevInst, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
67typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_PropertyW_)(LPCWSTR pszDeviceInterface, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
68typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_List_SizeW_)(PULONG pulLen, LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, ULONG ulFlags);
69typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_ListW_)(LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, WCHAR* /*PZZWSTR*/ Buffer, ULONG BufferLen, ULONG ulFlags);
70
71// from devpkey.h
72static DEVPROPKEY DEVPKEY_NAME = { { 0xb725f130, 0x47ef, 0x101a, {0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac} }, 10 }; // DEVPROP_TYPE_STRING
73static DEVPROPKEY DEVPKEY_Device_Manufacturer = { { 0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0} }, 13 }; // DEVPROP_TYPE_STRING
74static DEVPROPKEY DEVPKEY_Device_InstanceId = { { 0x78c34fc8, 0x104a, 0x4aca, {0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57} }, 256 }; // DEVPROP_TYPE_STRING
75static DEVPROPKEY DEVPKEY_Device_HardwareIds = { { 0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0} }, 3 }; // DEVPROP_TYPE_STRING_LIST
76static DEVPROPKEY DEVPKEY_Device_CompatibleIds = { { 0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0} }, 4 }; // DEVPROP_TYPE_STRING_LIST
77static DEVPROPKEY DEVPKEY_Device_ContainerId = { { 0x8c7ed206, 0x3f8a, 0x4827, {0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c} }, 2 }; // DEVPROP_TYPE_GUID
78
79// from propkey.h
80static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_DeviceAddress = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 1 }; // DEVPROP_TYPE_STRING
81static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_Manufacturer = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 4 }; // DEVPROP_TYPE_STRING
82static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_ModelNumber = { { 0x2BD67D8B, 0x8BEB, 0x48D5, {0x87, 0xE0, 0x6C, 0xDA, 0x34, 0x28, 0x04, 0x0A} }, 5 }; // DEVPROP_TYPE_STRING
83
84#endif
85
86#endif /* HIDAPI_CFGMGR32_H */
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.c b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.c
new file mode 100644
index 0000000..6697d3c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.c
@@ -0,0 +1,990 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19#include "hidapi_descriptor_reconstruct.h"
20
21/**
22 * @brief References to report descriptor buffer.
23 *
24 */
25struct rd_buffer {
26 unsigned char* buf; /* Pointer to the array which stores the reconstructed descriptor */
27 size_t buf_size; /* Size of the buffer in bytes */
28 size_t byte_idx; /* Index of the next report byte to write to buf array */
29};
30
31/**
32 * @brief Function that appends a byte to encoded report descriptor buffer.
33 *
34 * @param[in] byte Single byte to append.
35 * @param rpt_desc Pointer to report descriptor buffer struct.
36 */
37static void rd_append_byte(unsigned char byte, struct rd_buffer* rpt_desc) {
38 if (rpt_desc->byte_idx < rpt_desc->buf_size) {
39 rpt_desc->buf[rpt_desc->byte_idx] = byte;
40 rpt_desc->byte_idx++;
41 }
42}
43
44/**
45 * @brief Writes a short report descriptor item according USB HID spec 1.11 chapter 6.2.2.2.
46 *
47 * @param[in] rd_item Enumeration identifying type (Main, Global, Local) and function (e.g Usage or Report Count) of the item.
48 * @param[in] data Data (Size depends on rd_item 0,1,2 or 4bytes).
49 * @param rpt_desc Pointer to report descriptor buffer struct.
50 *
51 * @return Returns 0 if successful, -1 for error.
52 */
53static int rd_write_short_item(rd_items rd_item, LONG64 data, struct rd_buffer* rpt_desc) {
54 if (rd_item & 0x03) {
55 // Invalid input data, last to bits are reserved for data size
56 return -1;
57 }
58
59 if (rd_item == rd_main_collection_end) {
60 // Item without data (1Byte prefix only)
61 unsigned char oneBytePrefix = (unsigned char) rd_item + 0x00;
62 rd_append_byte(oneBytePrefix, rpt_desc);
63 }
64 else if ((rd_item == rd_global_logical_minimum) ||
65 (rd_item == rd_global_logical_maximum) ||
66 (rd_item == rd_global_physical_minimum) ||
67 (rd_item == rd_global_physical_maximum)) {
68 // Item with signed integer data
69 if ((data >= -128) && (data <= 127)) {
70 // 1Byte prefix + 1Byte data
71 unsigned char oneBytePrefix = (unsigned char) rd_item + 0x01;
72 char localData = (char)data;
73 rd_append_byte(oneBytePrefix, rpt_desc);
74 rd_append_byte(localData & 0xFF, rpt_desc);
75 }
76 else if ((data >= -32768) && (data <= 32767)) {
77 // 1Byte prefix + 2Byte data
78 unsigned char oneBytePrefix = (unsigned char) rd_item + 0x02;
79 INT16 localData = (INT16)data;
80 rd_append_byte(oneBytePrefix, rpt_desc);
81 rd_append_byte(localData & 0xFF, rpt_desc);
82 rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
83 }
84 else if ((data >= -2147483648LL) && (data <= 2147483647)) {
85 // 1Byte prefix + 4Byte data
86 unsigned char oneBytePrefix = (unsigned char) rd_item + 0x03;
87 INT32 localData = (INT32)data;
88 rd_append_byte(oneBytePrefix, rpt_desc);
89 rd_append_byte(localData & 0xFF, rpt_desc);
90 rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
91 rd_append_byte(localData >> 16 & 0xFF, rpt_desc);
92 rd_append_byte(localData >> 24 & 0xFF, rpt_desc);
93 }
94 else {
95 // Data out of 32 bit signed integer range
96 return -1;
97 }
98 }
99 else {
100 // Item with unsigned integer data
101 if ((data >= 0) && (data <= 0xFF)) {
102 // 1Byte prefix + 1Byte data
103 unsigned char oneBytePrefix = (unsigned char) rd_item + 0x01;
104 unsigned char localData = (unsigned char)data;
105 rd_append_byte(oneBytePrefix, rpt_desc);
106 rd_append_byte(localData & 0xFF, rpt_desc);
107 }
108 else if ((data >= 0) && (data <= 0xFFFF)) {
109 // 1Byte prefix + 2Byte data
110 unsigned char oneBytePrefix = (unsigned char) rd_item + 0x02;
111 UINT16 localData = (UINT16)data;
112 rd_append_byte(oneBytePrefix, rpt_desc);
113 rd_append_byte(localData & 0xFF, rpt_desc);
114 rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
115 }
116 else if ((data >= 0) && (data <= 0xFFFFFFFF)) {
117 // 1Byte prefix + 4Byte data
118 unsigned char oneBytePrefix = (unsigned char) rd_item + 0x03;
119 UINT32 localData = (UINT32)data;
120 rd_append_byte(oneBytePrefix, rpt_desc);
121 rd_append_byte(localData & 0xFF, rpt_desc);
122 rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
123 rd_append_byte(localData >> 16 & 0xFF, rpt_desc);
124 rd_append_byte(localData >> 24 & 0xFF, rpt_desc);
125 }
126 else {
127 // Data out of 32 bit unsigned integer range
128 return -1;
129 }
130 }
131 return 0;
132}
133
134static struct rd_main_item_node * rd_append_main_item_node(int first_bit, int last_bit, rd_node_type type_of_node, int caps_index, int collection_index, rd_main_items main_item_type, unsigned char report_id, struct rd_main_item_node **list) {
135 struct rd_main_item_node *new_list_node;
136
137 // Determine last node in the list
138 while (*list != NULL)
139 {
140 list = &(*list)->next;
141 }
142
143 new_list_node = malloc(sizeof(*new_list_node)); // Create new list entry
144 new_list_node->FirstBit = first_bit;
145 new_list_node->LastBit = last_bit;
146 new_list_node->TypeOfNode = type_of_node;
147 new_list_node->CapsIndex = caps_index;
148 new_list_node->CollectionIndex = collection_index;
149 new_list_node->MainItemType = main_item_type;
150 new_list_node->ReportID = report_id;
151 new_list_node->next = NULL; // NULL marks last node in the list
152
153 *list = new_list_node;
154 return new_list_node;
155}
156
157static struct rd_main_item_node * rd_insert_main_item_node(int first_bit, int last_bit, rd_node_type type_of_node, int caps_index, int collection_index, rd_main_items main_item_type, unsigned char report_id, struct rd_main_item_node **list) {
158 // Insert item after the main item node referenced by list
159 struct rd_main_item_node *next_item = (*list)->next;
160 (*list)->next = NULL;
161 rd_append_main_item_node(first_bit, last_bit, type_of_node, caps_index, collection_index, main_item_type, report_id, list);
162 (*list)->next->next = next_item;
163 return (*list)->next;
164}
165
166static struct rd_main_item_node * rd_search_main_item_list_for_bit_position(int search_bit, rd_main_items main_item_type, unsigned char report_id, struct rd_main_item_node **list) {
167 // Determine first INPUT/OUTPUT/FEATURE main item, where the last bit position is equal or greater than the search bit position
168
169 while (((*list)->next->MainItemType != rd_collection) &&
170 ((*list)->next->MainItemType != rd_collection_end) &&
171 !(((*list)->next->LastBit >= search_bit) &&
172 ((*list)->next->ReportID == report_id) &&
173 ((*list)->next->MainItemType == main_item_type))
174 )
175 {
176 list = &(*list)->next;
177 }
178 return *list;
179}
180
181int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned char *buf, size_t buf_size)
182{
183 hidp_preparsed_data *pp_data = (hidp_preparsed_data *) preparsed_data;
184
185 // Check if MagicKey is correct, to ensure that pp_data points to an valid preparse data structure
186 if (memcmp(pp_data->MagicKey, "HidP KDR", 8) != 0) {
187 return -1;
188 }
189
190 struct rd_buffer rpt_desc;
191 rpt_desc.buf = buf;
192 rpt_desc.buf_size = buf_size;
193 rpt_desc.byte_idx = 0;
194
195 // Set pointer to the first node of link_collection_nodes
196 phid_pp_link_collection_node link_collection_nodes = (phid_pp_link_collection_node)(((unsigned char*)&pp_data->caps[0]) + pp_data->FirstByteOfLinkCollectionArray);
197
198 // ****************************************************************************************************************************
199 // Create lookup tables for the bit range of each report per collection (position of first bit and last bit in each collection)
200 // coll_bit_range[COLLECTION_INDEX][REPORT_ID][INPUT/OUTPUT/FEATURE]
201 // ****************************************************************************************************************************
202
203 // Allocate memory and initialize lookup table
204 rd_bit_range ****coll_bit_range;
205 coll_bit_range = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_bit_range));
206 for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
207 coll_bit_range[collection_node_idx] = malloc(256 * sizeof(*coll_bit_range[0])); // 256 possible report IDs (incl. 0x00)
208 for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
209 coll_bit_range[collection_node_idx][reportid_idx] = malloc(NUM_OF_HIDP_REPORT_TYPES * sizeof(*coll_bit_range[0][0]));
210 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
211 coll_bit_range[collection_node_idx][reportid_idx][rt_idx] = malloc(sizeof(rd_bit_range));
212 coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->FirstBit = -1;
213 coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->LastBit = -1;
214 }
215 }
216 }
217
218 // Fill the lookup table where caps exist
219 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
220 for (USHORT caps_idx = pp_data->caps_info[rt_idx].FirstCap; caps_idx < pp_data->caps_info[rt_idx].LastCap; caps_idx++) {
221 int first_bit, last_bit;
222 first_bit = (pp_data->caps[caps_idx].BytePosition - 1) * 8
223 + pp_data->caps[caps_idx].BitPosition;
224 last_bit = first_bit + pp_data->caps[caps_idx].ReportSize
225 * pp_data->caps[caps_idx].ReportCount - 1;
226 if (coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit == -1 ||
227 coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit > first_bit) {
228 coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit = first_bit;
229 }
230 if (coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->LastBit < last_bit) {
231 coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->LastBit = last_bit;
232 }
233 }
234 }
235
236 // *************************************************************************
237 // -Determine hierarchy levels of each collections and store it in:
238 // coll_levels[COLLECTION_INDEX]
239 // -Determine number of direct childs of each collections and store it in:
240 // coll_number_of_direct_childs[COLLECTION_INDEX]
241 // *************************************************************************
242 int max_coll_level = 0;
243 int *coll_levels = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_levels[0]));
244 int *coll_number_of_direct_childs = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_number_of_direct_childs[0]));
245 for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
246 coll_levels[collection_node_idx] = -1;
247 coll_number_of_direct_childs[collection_node_idx] = 0;
248 }
249
250 {
251 int actual_coll_level = 0;
252 USHORT collection_node_idx = 0;
253 while (actual_coll_level >= 0) {
254 coll_levels[collection_node_idx] = actual_coll_level;
255 if ((link_collection_nodes[collection_node_idx].NumberOfChildren > 0) &&
256 (coll_levels[link_collection_nodes[collection_node_idx].FirstChild] == -1)) {
257 actual_coll_level++;
258 coll_levels[collection_node_idx] = actual_coll_level;
259 if (max_coll_level < actual_coll_level) {
260 max_coll_level = actual_coll_level;
261 }
262 coll_number_of_direct_childs[collection_node_idx]++;
263 collection_node_idx = link_collection_nodes[collection_node_idx].FirstChild;
264 }
265 else if (link_collection_nodes[collection_node_idx].NextSibling != 0) {
266 coll_number_of_direct_childs[link_collection_nodes[collection_node_idx].Parent]++;
267 collection_node_idx = link_collection_nodes[collection_node_idx].NextSibling;
268 }
269 else {
270 actual_coll_level--;
271 if (actual_coll_level >= 0) {
272 collection_node_idx = link_collection_nodes[collection_node_idx].Parent;
273 }
274 }
275 }
276 }
277
278 // *********************************************************************************
279 // Propagate the bit range of each report from the child collections to their parent
280 // and store the merged result for the parent
281 // *********************************************************************************
282 for (int actual_coll_level = max_coll_level - 1; actual_coll_level >= 0; actual_coll_level--) {
283 for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
284 if (coll_levels[collection_node_idx] == actual_coll_level) {
285 USHORT child_idx = link_collection_nodes[collection_node_idx].FirstChild;
286 while (child_idx) {
287 for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
288 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
289 // Merge bit range from childs
290 if ((coll_bit_range[child_idx][reportid_idx][rt_idx]->FirstBit != -1) &&
291 (coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->FirstBit > coll_bit_range[child_idx][reportid_idx][rt_idx]->FirstBit)) {
292 coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->FirstBit = coll_bit_range[child_idx][reportid_idx][rt_idx]->FirstBit;
293 }
294 if (coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->LastBit < coll_bit_range[child_idx][reportid_idx][rt_idx]->LastBit) {
295 coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->LastBit = coll_bit_range[child_idx][reportid_idx][rt_idx]->LastBit;
296 }
297 child_idx = link_collection_nodes[child_idx].NextSibling;
298 }
299 }
300 }
301 }
302 }
303 }
304
305 // **************************************************************************************************
306 // Determine child collection order of the whole hierarchy, based on previously determined bit ranges
307 // and store it this index coll_child_order[COLLECTION_INDEX][DIRECT_CHILD_INDEX]
308 // **************************************************************************************************
309 USHORT **coll_child_order;
310 coll_child_order = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_child_order));
311 {
312 BOOLEAN *coll_parsed_flag;
313 coll_parsed_flag = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_parsed_flag[0]));
314 for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
315 coll_parsed_flag[collection_node_idx] = FALSE;
316 }
317 int actual_coll_level = 0;
318 USHORT collection_node_idx = 0;
319 while (actual_coll_level >= 0) {
320 if ((coll_number_of_direct_childs[collection_node_idx] != 0) &&
321 (coll_parsed_flag[link_collection_nodes[collection_node_idx].FirstChild] == FALSE)) {
322 coll_parsed_flag[link_collection_nodes[collection_node_idx].FirstChild] = TRUE;
323 coll_child_order[collection_node_idx] = malloc((coll_number_of_direct_childs[collection_node_idx]) * sizeof(*coll_child_order[0]));
324
325 {
326 // Create list of child collection indices
327 // sorted reverse to the order returned to HidP_GetLinkCollectionNodeschild
328 // which seems to match the original order, as long as no bit position needs to be considered
329 USHORT child_idx = link_collection_nodes[collection_node_idx].FirstChild;
330 int child_count = coll_number_of_direct_childs[collection_node_idx] - 1;
331 coll_child_order[collection_node_idx][child_count] = child_idx;
332 while (link_collection_nodes[child_idx].NextSibling) {
333 child_count--;
334 child_idx = link_collection_nodes[child_idx].NextSibling;
335 coll_child_order[collection_node_idx][child_count] = child_idx;
336 }
337 }
338
339 if (coll_number_of_direct_childs[collection_node_idx] > 1) {
340 // Sort child collections indices by bit positions
341 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
342 for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
343 for (int child_idx = 1; child_idx < coll_number_of_direct_childs[collection_node_idx]; child_idx++) {
344 // since the coll_bit_range array is not sorted, we need to reference the collection index in
345 // our sorted coll_child_order array, and look up the corresponding bit ranges for comparing values to sort
346 int prev_coll_idx = coll_child_order[collection_node_idx][child_idx - 1];
347 int cur_coll_idx = coll_child_order[collection_node_idx][child_idx];
348 if ((coll_bit_range[prev_coll_idx][reportid_idx][rt_idx]->FirstBit != -1) &&
349 (coll_bit_range[cur_coll_idx][reportid_idx][rt_idx]->FirstBit != -1) &&
350 (coll_bit_range[prev_coll_idx][reportid_idx][rt_idx]->FirstBit > coll_bit_range[cur_coll_idx][reportid_idx][rt_idx]->FirstBit)) {
351 // Swap position indices of the two compared child collections
352 USHORT idx_latch = coll_child_order[collection_node_idx][child_idx - 1];
353 coll_child_order[collection_node_idx][child_idx - 1] = coll_child_order[collection_node_idx][child_idx];
354 coll_child_order[collection_node_idx][child_idx] = idx_latch;
355 }
356 }
357 }
358 }
359 }
360 actual_coll_level++;
361 collection_node_idx = link_collection_nodes[collection_node_idx].FirstChild;
362 }
363 else if (link_collection_nodes[collection_node_idx].NextSibling != 0) {
364 collection_node_idx = link_collection_nodes[collection_node_idx].NextSibling;
365 }
366 else {
367 actual_coll_level--;
368 if (actual_coll_level >= 0) {
369 collection_node_idx = link_collection_nodes[collection_node_idx].Parent;
370 }
371 }
372 }
373 free(coll_parsed_flag);
374 }
375
376
377 // ***************************************************************************************
378 // Create sorted main_item_list containing all the Collection and CollectionEnd main items
379 // ***************************************************************************************
380 struct rd_main_item_node *main_item_list = NULL; // List root
381 // Lookup table to find the Collection items in the list by index
382 struct rd_main_item_node **coll_begin_lookup = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_begin_lookup));
383 struct rd_main_item_node **coll_end_lookup = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_end_lookup));
384 {
385 int *coll_last_written_child = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_last_written_child[0]));
386 for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
387 coll_last_written_child[collection_node_idx] = -1;
388 }
389
390 int actual_coll_level = 0;
391 USHORT collection_node_idx = 0;
392 struct rd_main_item_node *firstDelimiterNode = NULL;
393 struct rd_main_item_node *delimiterCloseNode = NULL;
394 coll_begin_lookup[0] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection, 0, &main_item_list);
395 while (actual_coll_level >= 0) {
396 if ((coll_number_of_direct_childs[collection_node_idx] != 0) &&
397 (coll_last_written_child[collection_node_idx] == -1)) {
398 // Collection has child collections, but none is written to the list yet
399
400 coll_last_written_child[collection_node_idx] = coll_child_order[collection_node_idx][0];
401 collection_node_idx = coll_child_order[collection_node_idx][0];
402
403 // In a HID Report Descriptor, the first usage declared is the most preferred usage for the control.
404 // While the order in the WIN32 capabiliy strutures is the opposite:
405 // Here the preferred usage is the last aliased usage in the sequence.
406
407 if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode == NULL)) {
408 // Alliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output)
409 firstDelimiterNode = main_item_list;
410 coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &main_item_list);
411 coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_close, 0, &main_item_list);
412 delimiterCloseNode = main_item_list;
413 }
414 else {
415 // Normal not aliased collection
416 coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection, 0, &main_item_list);
417 actual_coll_level++;
418 }
419
420
421 }
422 else if ((coll_number_of_direct_childs[collection_node_idx] > 1) &&
423 (coll_last_written_child[collection_node_idx] != coll_child_order[collection_node_idx][coll_number_of_direct_childs[collection_node_idx] - 1])) {
424 // Collection has child collections, and this is not the first child
425
426 int nextChild = 1;
427 while (coll_last_written_child[collection_node_idx] != coll_child_order[collection_node_idx][nextChild - 1]) {
428 nextChild++;
429 }
430 coll_last_written_child[collection_node_idx] = coll_child_order[collection_node_idx][nextChild];
431 collection_node_idx = coll_child_order[collection_node_idx][nextChild];
432
433 if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode == NULL)) {
434 // Alliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output)
435 firstDelimiterNode = main_item_list;
436 coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &main_item_list);
437 coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_close, 0, &main_item_list);
438 delimiterCloseNode = main_item_list;
439 }
440 else if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode != NULL)) {
441 coll_begin_lookup[collection_node_idx] = rd_insert_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &firstDelimiterNode);
442 }
443 else if (!link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode != NULL)) {
444 coll_begin_lookup[collection_node_idx] = rd_insert_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &firstDelimiterNode);
445 coll_begin_lookup[collection_node_idx] = rd_insert_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_open, 0, &firstDelimiterNode);
446 firstDelimiterNode = NULL;
447 main_item_list = delimiterCloseNode;
448 delimiterCloseNode = NULL; // Last entry of alias has .IsAlias == FALSE
449 }
450 if (!link_collection_nodes[collection_node_idx].IsAlias) {
451 coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection, 0, &main_item_list);
452 actual_coll_level++;
453 }
454 }
455 else {
456 actual_coll_level--;
457 coll_end_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection_end, 0, &main_item_list);
458 collection_node_idx = link_collection_nodes[collection_node_idx].Parent;
459 }
460 }
461 free(coll_last_written_child);
462 }
463
464
465 // ****************************************************************
466 // Inserted Input/Output/Feature main items into the main_item_list
467 // in order of reconstructed bit positions
468 // ****************************************************************
469 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
470 // Add all value caps to node list
471 struct rd_main_item_node *firstDelimiterNode = NULL;
472 struct rd_main_item_node *delimiterCloseNode = NULL;
473 for (USHORT caps_idx = pp_data->caps_info[rt_idx].FirstCap; caps_idx < pp_data->caps_info[rt_idx].LastCap; caps_idx++) {
474 struct rd_main_item_node *coll_begin = coll_begin_lookup[pp_data->caps[caps_idx].LinkCollection];
475 int first_bit, last_bit;
476 first_bit = (pp_data->caps[caps_idx].BytePosition - 1) * 8 +
477 pp_data->caps[caps_idx].BitPosition;
478 last_bit = first_bit + pp_data->caps[caps_idx].ReportSize *
479 pp_data->caps[caps_idx].ReportCount - 1;
480
481 for (int child_idx = 0; child_idx < coll_number_of_direct_childs[pp_data->caps[caps_idx].LinkCollection]; child_idx++) {
482 // Determine in which section before/between/after child collection the item should be inserted
483 if (first_bit < coll_bit_range[coll_child_order[pp_data->caps[caps_idx].LinkCollection][child_idx]][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit)
484 {
485 // Note, that the default value for undefined coll_bit_range is -1, which can't be greater than the bit position
486 break;
487 }
488 coll_begin = coll_end_lookup[coll_child_order[pp_data->caps[caps_idx].LinkCollection][child_idx]];
489 }
490 struct rd_main_item_node *list_node;
491 list_node = rd_search_main_item_list_for_bit_position(first_bit, (rd_main_items) rt_idx, pp_data->caps[caps_idx].ReportID, &coll_begin);
492
493 // In a HID Report Descriptor, the first usage declared is the most preferred usage for the control.
494 // While the order in the WIN32 capabiliy strutures is the opposite:
495 // Here the preferred usage is the last aliased usage in the sequence.
496
497 if (pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode == NULL)) {
498 // Alliased Usage (First node in pp_data->caps -> Last entry in report descriptor output)
499 firstDelimiterNode = list_node;
500 rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node);
501 rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_close, pp_data->caps[caps_idx].ReportID, &list_node);
502 delimiterCloseNode = list_node;
503 } else if (pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode != NULL)) {
504 rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node);
505 }
506 else if (!pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode != NULL)) {
507 // Alliased Collection (Last node in pp_data->caps -> First entry in report descriptor output)
508 rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node);
509 rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_open, pp_data->caps[caps_idx].ReportID, &list_node);
510 firstDelimiterNode = NULL;
511 list_node = delimiterCloseNode;
512 delimiterCloseNode = NULL; // Last entry of alias has .IsAlias == FALSE
513 }
514 if (!pp_data->caps[caps_idx].IsAlias) {
515 rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, (rd_main_items) rt_idx, pp_data->caps[caps_idx].ReportID, &list_node);
516 }
517 }
518 }
519
520
521 // ***********************************************************
522 // Add const main items for padding to main_item_list
523 // -To fill all bit gaps
524 // -At each report end for 8bit padding
525 // Note that information about the padding at the report end,
526 // is not stored in the preparsed data, but in practice all
527 // report descriptors seem to have it, as assumed here.
528 // ***********************************************************
529 {
530 int *last_bit_position[NUM_OF_HIDP_REPORT_TYPES];
531 struct rd_main_item_node **last_report_item_lookup[NUM_OF_HIDP_REPORT_TYPES];
532 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
533 last_bit_position[rt_idx] = malloc(256 * sizeof(*last_bit_position[rt_idx]));
534 last_report_item_lookup[rt_idx] = malloc(256 * sizeof(*last_report_item_lookup[rt_idx]));
535 for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
536 last_bit_position[rt_idx][reportid_idx] = -1;
537 last_report_item_lookup[rt_idx][reportid_idx] = NULL;
538 }
539 }
540
541 struct rd_main_item_node *list = main_item_list; // List root;
542
543 while (list->next != NULL)
544 {
545 if ((list->MainItemType >= rd_input) &&
546 (list->MainItemType <= rd_feature)) {
547 // INPUT, OUTPUT or FEATURE
548 if (list->FirstBit != -1) {
549 if ((last_bit_position[list->MainItemType][list->ReportID] + 1 != list->FirstBit) &&
550 (last_report_item_lookup[list->MainItemType][list->ReportID] != NULL) &&
551 (last_report_item_lookup[list->MainItemType][list->ReportID]->FirstBit != list->FirstBit) // Happens in case of IsMultipleItemsForArray for multiple dedicated usages for a multi-button array
552 ) {
553 struct rd_main_item_node *list_node = rd_search_main_item_list_for_bit_position(last_bit_position[list->MainItemType][list->ReportID], list->MainItemType, list->ReportID, &last_report_item_lookup[list->MainItemType][list->ReportID]);
554 rd_insert_main_item_node(last_bit_position[list->MainItemType][list->ReportID] + 1, list->FirstBit - 1, rd_item_node_padding, -1, 0, list->MainItemType, list->ReportID, &list_node);
555 }
556 last_bit_position[list->MainItemType][list->ReportID] = list->LastBit;
557 last_report_item_lookup[list->MainItemType][list->ReportID] = list;
558 }
559 }
560 list = list->next;
561 }
562 // Add 8 bit padding at each report end
563 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
564 for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
565 if (last_bit_position[rt_idx][reportid_idx] != -1) {
566 int padding = 8 - ((last_bit_position[rt_idx][reportid_idx] + 1) % 8);
567 if (padding < 8) {
568 // Insert padding item after item referenced in last_report_item_lookup
569 rd_insert_main_item_node(last_bit_position[rt_idx][reportid_idx] + 1, last_bit_position[rt_idx][reportid_idx] + padding, rd_item_node_padding, -1, 0, (rd_main_items) rt_idx, (unsigned char) reportid_idx, &last_report_item_lookup[rt_idx][reportid_idx]);
570 }
571 }
572 }
573 free(last_bit_position[rt_idx]);
574 free(last_report_item_lookup[rt_idx]);
575 }
576 }
577
578
579 // ***********************************
580 // Encode the report descriptor output
581 // ***********************************
582 UCHAR last_report_id = 0;
583 USAGE last_usage_page = 0;
584 LONG last_physical_min = 0;// If both, Physical Minimum and Physical Maximum are 0, the logical limits should be taken as physical limits according USB HID spec 1.11 chapter 6.2.2.7
585 LONG last_physical_max = 0;
586 ULONG last_unit_exponent = 0; // If Unit Exponent is Undefined it should be considered as 0 according USB HID spec 1.11 chapter 6.2.2.7
587 ULONG last_unit = 0; // If the first nibble is 7, or second nibble of Unit is 0, the unit is None according USB HID spec 1.11 chapter 6.2.2.7
588 BOOLEAN inhibit_write_of_usage = FALSE; // Needed in case of delimited usage print, before the normal collection or cap
589 int report_count = 0;
590 while (main_item_list != NULL)
591 {
592 int rt_idx = main_item_list->MainItemType;
593 int caps_idx = main_item_list->CapsIndex;
594 if (main_item_list->MainItemType == rd_collection) {
595 if (last_usage_page != link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage) {
596 // Write "Usage Page" at the begin of a collection - except it refers the same table as wrote last
597 rd_write_short_item(rd_global_usage_page, link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage, &rpt_desc);
598 last_usage_page = link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage;
599 }
600 if (inhibit_write_of_usage) {
601 // Inhibit only once after DELIMITER statement
602 inhibit_write_of_usage = FALSE;
603 }
604 else {
605 // Write "Usage" of collection
606 rd_write_short_item(rd_local_usage, link_collection_nodes[main_item_list->CollectionIndex].LinkUsage, &rpt_desc);
607 }
608 // Write begin of "Collection"
609 rd_write_short_item(rd_main_collection, link_collection_nodes[main_item_list->CollectionIndex].CollectionType, &rpt_desc);
610 }
611 else if (main_item_list->MainItemType == rd_collection_end) {
612 // Write "End Collection"
613 rd_write_short_item(rd_main_collection_end, 0, &rpt_desc);
614 }
615 else if (main_item_list->MainItemType == rd_delimiter_open) {
616 if (main_item_list->CollectionIndex != -1) {
617 // Write "Usage Page" inside of a collection delmiter section
618 if (last_usage_page != link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage) {
619 rd_write_short_item(rd_global_usage_page, link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage, &rpt_desc);
620 last_usage_page = link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage;
621 }
622 }
623 else if (main_item_list->CapsIndex != 0) {
624 // Write "Usage Page" inside of a main item delmiter section
625 if (pp_data->caps[caps_idx].UsagePage != last_usage_page) {
626 rd_write_short_item(rd_global_usage_page, pp_data->caps[caps_idx].UsagePage, &rpt_desc);
627 last_usage_page = pp_data->caps[caps_idx].UsagePage;
628 }
629 }
630 // Write "Delimiter Open"
631 rd_write_short_item(rd_local_delimiter, 1, &rpt_desc); // 1 = open set of aliased usages
632 }
633 else if (main_item_list->MainItemType == rd_delimiter_usage) {
634 if (main_item_list->CollectionIndex != -1) {
635 // Write aliased collection "Usage"
636 rd_write_short_item(rd_local_usage, link_collection_nodes[main_item_list->CollectionIndex].LinkUsage, &rpt_desc);
637 } if (main_item_list->CapsIndex != 0) {
638 // Write aliased main item range from "Usage Minimum" to "Usage Maximum"
639 if (pp_data->caps[caps_idx].IsRange) {
640 rd_write_short_item(rd_local_usage_minimum, pp_data->caps[caps_idx].Range.UsageMin, &rpt_desc);
641 rd_write_short_item(rd_local_usage_maximum, pp_data->caps[caps_idx].Range.UsageMax, &rpt_desc);
642 }
643 else {
644 // Write single aliased main item "Usage"
645 rd_write_short_item(rd_local_usage, pp_data->caps[caps_idx].NotRange.Usage, &rpt_desc);
646 }
647 }
648 }
649 else if (main_item_list->MainItemType == rd_delimiter_close) {
650 // Write "Delimiter Close"
651 rd_write_short_item(rd_local_delimiter, 0, &rpt_desc); // 0 = close set of aliased usages
652 // Inhibit next usage write
653 inhibit_write_of_usage = TRUE;
654 }
655 else if (main_item_list->TypeOfNode == rd_item_node_padding) {
656 // Padding
657 // The preparsed data doesn't contain any information about padding. Therefore all undefined gaps
658 // in the reports are filled with the same style of constant padding.
659
660 // Write "Report Size" with number of padding bits
661 rd_write_short_item(rd_global_report_size, (main_item_list->LastBit - main_item_list->FirstBit + 1), &rpt_desc);
662
663 // Write "Report Count" for padding always as 1
664 rd_write_short_item(rd_global_report_count, 1, &rpt_desc);
665
666 if (rt_idx == HidP_Input) {
667 // Write "Input" main item - We know it's Constant - We can only guess the other bits, but they don't matter in case of const
668 rd_write_short_item(rd_main_input, 0x03, &rpt_desc); // Const / Abs
669 }
670 else if (rt_idx == HidP_Output) {
671 // Write "Output" main item - We know it's Constant - We can only guess the other bits, but they don't matter in case of const
672 rd_write_short_item(rd_main_output, 0x03, &rpt_desc); // Const / Abs
673 }
674 else if (rt_idx == HidP_Feature) {
675 // Write "Feature" main item - We know it's Constant - We can only guess the other bits, but they don't matter in case of const
676 rd_write_short_item(rd_main_feature, 0x03, &rpt_desc); // Const / Abs
677 }
678 report_count = 0;
679 }
680 else if (pp_data->caps[caps_idx].IsButtonCap) {
681 // Button
682 // (The preparsed data contain different data for 1 bit Button caps, than for parametric Value caps)
683
684 if (last_report_id != pp_data->caps[caps_idx].ReportID) {
685 // Write "Report ID" if changed
686 rd_write_short_item(rd_global_report_id, pp_data->caps[caps_idx].ReportID, &rpt_desc);
687 last_report_id = pp_data->caps[caps_idx].ReportID;
688 }
689
690 // Write "Usage Page" when changed
691 if (pp_data->caps[caps_idx].UsagePage != last_usage_page) {
692 rd_write_short_item(rd_global_usage_page, pp_data->caps[caps_idx].UsagePage, &rpt_desc);
693 last_usage_page = pp_data->caps[caps_idx].UsagePage;
694 }
695
696 // Write only local report items for each cap, if ReportCount > 1
697 if (pp_data->caps[caps_idx].IsRange) {
698 report_count += (pp_data->caps[caps_idx].Range.DataIndexMax - pp_data->caps[caps_idx].Range.DataIndexMin);
699 }
700
701 if (inhibit_write_of_usage) {
702 // Inhibit only once after Delimiter - Reset flag
703 inhibit_write_of_usage = FALSE;
704 }
705 else {
706 if (pp_data->caps[caps_idx].IsRange) {
707 // Write range from "Usage Minimum" to "Usage Maximum"
708 rd_write_short_item(rd_local_usage_minimum, pp_data->caps[caps_idx].Range.UsageMin, &rpt_desc);
709 rd_write_short_item(rd_local_usage_maximum, pp_data->caps[caps_idx].Range.UsageMax, &rpt_desc);
710 }
711 else {
712 // Write single "Usage"
713 rd_write_short_item(rd_local_usage, pp_data->caps[caps_idx].NotRange.Usage, &rpt_desc);
714 }
715 }
716
717 if (pp_data->caps[caps_idx].IsDesignatorRange) {
718 // Write physical descriptor indices range from "Designator Minimum" to "Designator Maximum"
719 rd_write_short_item(rd_local_designator_minimum, pp_data->caps[caps_idx].Range.DesignatorMin, &rpt_desc);
720 rd_write_short_item(rd_local_designator_maximum, pp_data->caps[caps_idx].Range.DesignatorMax, &rpt_desc);
721 }
722 else if (pp_data->caps[caps_idx].NotRange.DesignatorIndex != 0) {
723 // Designator set 0 is a special descriptor set (of the HID Physical Descriptor),
724 // that specifies the number of additional descriptor sets.
725 // Therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
726 // Write single "Designator Index"
727 rd_write_short_item(rd_local_designator_index, pp_data->caps[caps_idx].NotRange.DesignatorIndex, &rpt_desc);
728 }
729
730 if (pp_data->caps[caps_idx].IsStringRange) {
731 // Write range of indices of the USB string descriptor, from "String Minimum" to "String Maximum"
732 rd_write_short_item(rd_local_string_minimum, pp_data->caps[caps_idx].Range.StringMin, &rpt_desc);
733 rd_write_short_item(rd_local_string_maximum, pp_data->caps[caps_idx].Range.StringMax, &rpt_desc);
734 }
735 else if (pp_data->caps[caps_idx].NotRange.StringIndex != 0) {
736 // String Index 0 is a special entry of the USB string descriptor, that contains a list of supported languages,
737 // therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
738 // Write single "String Index"
739 rd_write_short_item(rd_local_string, pp_data->caps[caps_idx].NotRange.StringIndex, &rpt_desc);
740 }
741
742 if ((main_item_list->next != NULL) &&
743 ((int)main_item_list->next->MainItemType == rt_idx) &&
744 (main_item_list->next->TypeOfNode == rd_item_node_cap) &&
745 (pp_data->caps[main_item_list->next->CapsIndex].IsButtonCap) &&
746 (!pp_data->caps[caps_idx].IsRange) && // This node in list is no array
747 (!pp_data->caps[main_item_list->next->CapsIndex].IsRange) && // Next node in list is no array
748 (pp_data->caps[main_item_list->next->CapsIndex].UsagePage == pp_data->caps[caps_idx].UsagePage) &&
749 (pp_data->caps[main_item_list->next->CapsIndex].ReportID == pp_data->caps[caps_idx].ReportID) &&
750 (pp_data->caps[main_item_list->next->CapsIndex].BitField == pp_data->caps[caps_idx].BitField)
751 ) {
752 if (main_item_list->next->FirstBit != main_item_list->FirstBit) {
753 // In case of IsMultipleItemsForArray for multiple dedicated usages for a multi-button array, the report count should be incremented
754
755 // Skip global items until any of them changes, than use ReportCount item to write the count of identical report fields
756 report_count++;
757 }
758 }
759 else {
760
761 if ((pp_data->caps[caps_idx].Button.LogicalMin == 0) &&
762 (pp_data->caps[caps_idx].Button.LogicalMax == 0)) {
763 // While a HID report descriptor must always contain LogicalMinimum and LogicalMaximum,
764 // the preparsed data contain both fields set to zero, for the case of simple buttons
765 // Write "Logical Minimum" set to 0 and "Logical Maximum" set to 1
766 rd_write_short_item(rd_global_logical_minimum, 0, &rpt_desc);
767 rd_write_short_item(rd_global_logical_maximum, 1, &rpt_desc);
768 }
769 else {
770 // Write logical range from "Logical Minimum" to "Logical Maximum"
771 rd_write_short_item(rd_global_logical_minimum, pp_data->caps[caps_idx].Button.LogicalMin, &rpt_desc);
772 rd_write_short_item(rd_global_logical_maximum, pp_data->caps[caps_idx].Button.LogicalMax, &rpt_desc);
773 }
774
775 // Write "Report Size"
776 rd_write_short_item(rd_global_report_size, pp_data->caps[caps_idx].ReportSize, &rpt_desc);
777
778 // Write "Report Count"
779 if (!pp_data->caps[caps_idx].IsRange) {
780 // Variable bit field with one bit per button
781 // In case of multiple usages with the same items, only "Usage" is written per cap, and "Report Count" is incremented
782 rd_write_short_item(rd_global_report_count, pp_data->caps[caps_idx].ReportCount + report_count, &rpt_desc);
783 }
784 else {
785 // Button array of "Report Size" x "Report Count
786 rd_write_short_item(rd_global_report_count, pp_data->caps[caps_idx].ReportCount, &rpt_desc);
787 }
788
789
790 // Buttons have only 1 bit and therefore no physical limits/units -> Set to undefined state
791 if (last_physical_min != 0) {
792 // Write "Physical Minimum", but only if changed
793 last_physical_min = 0;
794 rd_write_short_item(rd_global_physical_minimum, last_physical_min, &rpt_desc);
795 }
796 if (last_physical_max != 0) {
797 // Write "Physical Maximum", but only if changed
798 last_physical_max = 0;
799 rd_write_short_item(rd_global_physical_maximum, last_physical_max, &rpt_desc);
800 }
801 if (last_unit_exponent != 0) {
802 // Write "Unit Exponent", but only if changed
803 last_unit_exponent = 0;
804 rd_write_short_item(rd_global_unit_exponent, last_unit_exponent, &rpt_desc);
805 }
806 if (last_unit != 0) {
807 // Write "Unit",but only if changed
808 last_unit = 0;
809 rd_write_short_item(rd_global_unit, last_unit, &rpt_desc);
810 }
811
812 // Write "Input" main item
813 if (rt_idx == HidP_Input) {
814 rd_write_short_item(rd_main_input, pp_data->caps[caps_idx].BitField, &rpt_desc);
815 }
816 // Write "Output" main item
817 else if (rt_idx == HidP_Output) {
818 rd_write_short_item(rd_main_output, pp_data->caps[caps_idx].BitField, &rpt_desc);
819 }
820 // Write "Feature" main item
821 else if (rt_idx == HidP_Feature) {
822 rd_write_short_item(rd_main_feature, pp_data->caps[caps_idx].BitField, &rpt_desc);
823 }
824 report_count = 0;
825 }
826 }
827 else {
828
829 if (last_report_id != pp_data->caps[caps_idx].ReportID) {
830 // Write "Report ID" if changed
831 rd_write_short_item(rd_global_report_id, pp_data->caps[caps_idx].ReportID, &rpt_desc);
832 last_report_id = pp_data->caps[caps_idx].ReportID;
833 }
834
835 // Write "Usage Page" if changed
836 if (pp_data->caps[caps_idx].UsagePage != last_usage_page) {
837 rd_write_short_item(rd_global_usage_page, pp_data->caps[caps_idx].UsagePage, &rpt_desc);
838 last_usage_page = pp_data->caps[caps_idx].UsagePage;
839 }
840
841 if (inhibit_write_of_usage) {
842 // Inhibit only once after Delimiter - Reset flag
843 inhibit_write_of_usage = FALSE;
844 }
845 else {
846 if (pp_data->caps[caps_idx].IsRange) {
847 // Write usage range from "Usage Minimum" to "Usage Maximum"
848 rd_write_short_item(rd_local_usage_minimum, pp_data->caps[caps_idx].Range.UsageMin, &rpt_desc);
849 rd_write_short_item(rd_local_usage_maximum, pp_data->caps[caps_idx].Range.UsageMax, &rpt_desc);
850 }
851 else {
852 // Write single "Usage"
853 rd_write_short_item(rd_local_usage, pp_data->caps[caps_idx].NotRange.Usage, &rpt_desc);
854 }
855 }
856
857 if (pp_data->caps[caps_idx].IsDesignatorRange) {
858 // Write physical descriptor indices range from "Designator Minimum" to "Designator Maximum"
859 rd_write_short_item(rd_local_designator_minimum, pp_data->caps[caps_idx].Range.DesignatorMin, &rpt_desc);
860 rd_write_short_item(rd_local_designator_maximum, pp_data->caps[caps_idx].Range.DesignatorMax, &rpt_desc);
861 }
862 else if (pp_data->caps[caps_idx].NotRange.DesignatorIndex != 0) {
863 // Designator set 0 is a special descriptor set (of the HID Physical Descriptor),
864 // that specifies the number of additional descriptor sets.
865 // Therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
866 // Write single "Designator Index"
867 rd_write_short_item(rd_local_designator_index, pp_data->caps[caps_idx].NotRange.DesignatorIndex, &rpt_desc);
868 }
869
870 if (pp_data->caps[caps_idx].IsStringRange) {
871 // Write range of indices of the USB string descriptor, from "String Minimum" to "String Maximum"
872 rd_write_short_item(rd_local_string_minimum, pp_data->caps[caps_idx].Range.StringMin, &rpt_desc);
873 rd_write_short_item(rd_local_string_maximum, pp_data->caps[caps_idx].Range.StringMax, &rpt_desc);
874 }
875 else if (pp_data->caps[caps_idx].NotRange.StringIndex != 0) {
876 // String Index 0 is a special entry of the USB string descriptor, that contains a list of supported languages,
877 // therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
878 // Write single "String Index"
879 rd_write_short_item(rd_local_string, pp_data->caps[caps_idx].NotRange.StringIndex, &rpt_desc);
880 }
881
882 if ((pp_data->caps[caps_idx].BitField & 0x02) != 0x02) {
883 // In case of an value array overwrite "Report Count"
884 pp_data->caps[caps_idx].ReportCount = pp_data->caps[caps_idx].Range.DataIndexMax - pp_data->caps[caps_idx].Range.DataIndexMin + 1;
885 }
886
887
888 // Print only local report items for each cap, if ReportCount > 1
889 if ((main_item_list->next != NULL) &&
890 ((int) main_item_list->next->MainItemType == rt_idx) &&
891 (main_item_list->next->TypeOfNode == rd_item_node_cap) &&
892 (!pp_data->caps[main_item_list->next->CapsIndex].IsButtonCap) &&
893 (!pp_data->caps[caps_idx].IsRange) && // This node in list is no array
894 (!pp_data->caps[main_item_list->next->CapsIndex].IsRange) && // Next node in list is no array
895 (pp_data->caps[main_item_list->next->CapsIndex].UsagePage == pp_data->caps[caps_idx].UsagePage) &&
896 (pp_data->caps[main_item_list->next->CapsIndex].NotButton.LogicalMin == pp_data->caps[caps_idx].NotButton.LogicalMin) &&
897 (pp_data->caps[main_item_list->next->CapsIndex].NotButton.LogicalMax == pp_data->caps[caps_idx].NotButton.LogicalMax) &&
898 (pp_data->caps[main_item_list->next->CapsIndex].NotButton.PhysicalMin == pp_data->caps[caps_idx].NotButton.PhysicalMin) &&
899 (pp_data->caps[main_item_list->next->CapsIndex].NotButton.PhysicalMax == pp_data->caps[caps_idx].NotButton.PhysicalMax) &&
900 (pp_data->caps[main_item_list->next->CapsIndex].UnitsExp == pp_data->caps[caps_idx].UnitsExp) &&
901 (pp_data->caps[main_item_list->next->CapsIndex].Units == pp_data->caps[caps_idx].Units) &&
902 (pp_data->caps[main_item_list->next->CapsIndex].ReportSize == pp_data->caps[caps_idx].ReportSize) &&
903 (pp_data->caps[main_item_list->next->CapsIndex].ReportID == pp_data->caps[caps_idx].ReportID) &&
904 (pp_data->caps[main_item_list->next->CapsIndex].BitField == pp_data->caps[caps_idx].BitField) &&
905 (pp_data->caps[main_item_list->next->CapsIndex].ReportCount == 1) &&
906 (pp_data->caps[caps_idx].ReportCount == 1)
907 ) {
908 // Skip global items until any of them changes, than use ReportCount item to write the count of identical report fields
909 report_count++;
910 }
911 else {
912 // Value
913
914 // Write logical range from "Logical Minimum" to "Logical Maximum"
915 rd_write_short_item(rd_global_logical_minimum, pp_data->caps[caps_idx].NotButton.LogicalMin, &rpt_desc);
916 rd_write_short_item(rd_global_logical_maximum, pp_data->caps[caps_idx].NotButton.LogicalMax, &rpt_desc);
917
918 if ((last_physical_min != pp_data->caps[caps_idx].NotButton.PhysicalMin) ||
919 (last_physical_max != pp_data->caps[caps_idx].NotButton.PhysicalMax)) {
920 // Write range from "Physical Minimum" to " Physical Maximum", but only if one of them changed
921 rd_write_short_item(rd_global_physical_minimum, pp_data->caps[caps_idx].NotButton.PhysicalMin, &rpt_desc);
922 last_physical_min = pp_data->caps[caps_idx].NotButton.PhysicalMin;
923 rd_write_short_item(rd_global_physical_maximum, pp_data->caps[caps_idx].NotButton.PhysicalMax, &rpt_desc);
924 last_physical_max = pp_data->caps[caps_idx].NotButton.PhysicalMax;
925 }
926
927
928 if (last_unit_exponent != pp_data->caps[caps_idx].UnitsExp) {
929 // Write "Unit Exponent", but only if changed
930 rd_write_short_item(rd_global_unit_exponent, pp_data->caps[caps_idx].UnitsExp, &rpt_desc);
931 last_unit_exponent = pp_data->caps[caps_idx].UnitsExp;
932 }
933
934 if (last_unit != pp_data->caps[caps_idx].Units) {
935 // Write physical "Unit", but only if changed
936 rd_write_short_item(rd_global_unit, pp_data->caps[caps_idx].Units, &rpt_desc);
937 last_unit = pp_data->caps[caps_idx].Units;
938 }
939
940 // Write "Report Size"
941 rd_write_short_item(rd_global_report_size, pp_data->caps[caps_idx].ReportSize, &rpt_desc);
942
943 // Write "Report Count"
944 rd_write_short_item(rd_global_report_count, pp_data->caps[caps_idx].ReportCount + report_count, &rpt_desc);
945
946 if (rt_idx == HidP_Input) {
947 // Write "Input" main item
948 rd_write_short_item(rd_main_input, pp_data->caps[caps_idx].BitField, &rpt_desc);
949 }
950 else if (rt_idx == HidP_Output) {
951 // Write "Output" main item
952 rd_write_short_item(rd_main_output, pp_data->caps[caps_idx].BitField, &rpt_desc);
953 }
954 else if (rt_idx == HidP_Feature) {
955 // Write "Feature" main item
956 rd_write_short_item(rd_main_feature, pp_data->caps[caps_idx].BitField, &rpt_desc);
957 }
958 report_count = 0;
959 }
960 }
961
962 // Go to next item in main_item_list and free the memory of the actual item
963 struct rd_main_item_node *main_item_list_prev = main_item_list;
964 main_item_list = main_item_list->next;
965 free(main_item_list_prev);
966 }
967
968 // Free multidimensionable array: coll_bit_range[COLLECTION_INDEX][REPORT_ID][INPUT/OUTPUT/FEATURE]
969 // Free multidimensionable array: coll_child_order[COLLECTION_INDEX][DIRECT_CHILD_INDEX]
970 for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
971 for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
972 for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
973 free(coll_bit_range[collection_node_idx][reportid_idx][rt_idx]);
974 }
975 free(coll_bit_range[collection_node_idx][reportid_idx]);
976 }
977 free(coll_bit_range[collection_node_idx]);
978 if (coll_number_of_direct_childs[collection_node_idx] != 0) free(coll_child_order[collection_node_idx]);
979 }
980 free(coll_bit_range);
981 free(coll_child_order);
982
983 // Free one dimensional arrays
984 free(coll_begin_lookup);
985 free(coll_end_lookup);
986 free(coll_levels);
987 free(coll_number_of_direct_childs);
988
989 return (int) rpt_desc.byte_idx;
990}
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.h b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.h
new file mode 100644
index 0000000..0bfe72b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_descriptor_reconstruct.h
@@ -0,0 +1,254 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19#include "SDL_internal.h"
20
21#ifndef HIDAPI_DESCRIPTOR_RECONSTRUCT_H__
22#define HIDAPI_DESCRIPTOR_RECONSTRUCT_H__
23
24#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
25/* Do not warn about wcsncpy usage.
26 https://docs.microsoft.com/cpp/c-runtime-library/security-features-in-the-crt */
27#define _CRT_SECURE_NO_WARNINGS
28#endif
29
30#include "hidapi_winapi.h"
31
32#ifdef _MSC_VER
33#pragma warning(push)
34#pragma warning(disable: 4200)
35#pragma warning(disable: 4201)
36#pragma warning(disable: 4214)
37#endif
38
39#include <windows.h>
40
41#include "hidapi_hidsdi.h"
42/*#include <assert.h>*/
43
44#define NUM_OF_HIDP_REPORT_TYPES 3
45
46typedef enum rd_items_ {
47 rd_main_input = 0x80, /* 1000 00 nn */
48 rd_main_output = 0x90, /* 1001 00 nn */
49 rd_main_feature = 0xB0, /* 1011 00 nn */
50 rd_main_collection = 0xA0, /* 1010 00 nn */
51 rd_main_collection_end = 0xC0, /* 1100 00 nn */
52 rd_global_usage_page = 0x04, /* 0000 01 nn */
53 rd_global_logical_minimum = 0x14, /* 0001 01 nn */
54 rd_global_logical_maximum = 0x24, /* 0010 01 nn */
55 rd_global_physical_minimum = 0x34, /* 0011 01 nn */
56 rd_global_physical_maximum = 0x44, /* 0100 01 nn */
57 rd_global_unit_exponent = 0x54, /* 0101 01 nn */
58 rd_global_unit = 0x64, /* 0110 01 nn */
59 rd_global_report_size = 0x74, /* 0111 01 nn */
60 rd_global_report_id = 0x84, /* 1000 01 nn */
61 rd_global_report_count = 0x94, /* 1001 01 nn */
62 rd_global_push = 0xA4, /* 1010 01 nn */
63 rd_global_pop = 0xB4, /* 1011 01 nn */
64 rd_local_usage = 0x08, /* 0000 10 nn */
65 rd_local_usage_minimum = 0x18, /* 0001 10 nn */
66 rd_local_usage_maximum = 0x28, /* 0010 10 nn */
67 rd_local_designator_index = 0x38, /* 0011 10 nn */
68 rd_local_designator_minimum = 0x48, /* 0100 10 nn */
69 rd_local_designator_maximum = 0x58, /* 0101 10 nn */
70 rd_local_string = 0x78, /* 0111 10 nn */
71 rd_local_string_minimum = 0x88, /* 1000 10 nn */
72 rd_local_string_maximum = 0x98, /* 1001 10 nn */
73 rd_local_delimiter = 0xA8 /* 1010 10 nn */
74} rd_items;
75
76typedef enum rd_main_items_ {
77 rd_input = HidP_Input,
78 rd_output = HidP_Output,
79 rd_feature = HidP_Feature,
80 rd_collection,
81 rd_collection_end,
82 rd_delimiter_open,
83 rd_delimiter_usage,
84 rd_delimiter_close,
85} rd_main_items;
86
87typedef struct rd_bit_range_ {
88 int FirstBit;
89 int LastBit;
90} rd_bit_range;
91
92typedef enum rd_item_node_type_ {
93 rd_item_node_cap,
94 rd_item_node_padding,
95 rd_item_node_collection,
96} rd_node_type;
97
98struct rd_main_item_node {
99 int FirstBit; /* Position of first bit in report (counting from 0) */
100 int LastBit; /* Position of last bit in report (counting from 0) */
101 rd_node_type TypeOfNode; /* Information if caps index refers to the array of button caps, value caps,
102 or if the node is just a padding element to fill unused bit positions.
103 The node can also be a collection node without any bits in the report. */
104 int CapsIndex; /* Index in the array of caps */
105 int CollectionIndex; /* Index in the array of link collections */
106 rd_main_items MainItemType; /* Input, Output, Feature, Collection or Collection End */
107 unsigned char ReportID;
108 struct rd_main_item_node* next;
109};
110
111typedef struct hid_pp_caps_info_ {
112 USHORT FirstCap;
113 USHORT NumberOfCaps; // Includes empty caps after LastCap
114 USHORT LastCap;
115 USHORT ReportByteLength;
116} hid_pp_caps_info, *phid_pp_caps_info;
117
118typedef struct hid_pp_link_collection_node_ {
119 USAGE LinkUsage;
120 USAGE LinkUsagePage;
121 USHORT Parent;
122 USHORT NumberOfChildren;
123 USHORT NextSibling;
124 USHORT FirstChild;
125 ULONG CollectionType : 8;
126 ULONG IsAlias : 1;
127 ULONG Reserved : 23;
128 // Same as the public API structure HIDP_LINK_COLLECTION_NODE, but without PVOID UserContext at the end
129} hid_pp_link_collection_node, *phid_pp_link_collection_node;
130
131// Note: This is risk-reduction-measure for this specific struct, as it has ULONG bit-field.
132// Although very unlikely, it might still be possible that the compiler creates a memory layout that is
133// not binary compatile.
134// Other structs are not checked at the time of writing.
135//static_assert(sizeof(struct hid_pp_link_collection_node_) == 16,
136// "Size of struct hid_pp_link_collection_node_ not as expected. This might break binary compatibility");
137SDL_COMPILE_TIME_ASSERT(hid_pp_link_collection_node_, sizeof(struct hid_pp_link_collection_node_) == 16);
138
139typedef struct hidp_unknown_token_ {
140 UCHAR Token; /* Specifies the one-byte prefix of a global item. */
141 UCHAR Reserved[3];
142 ULONG BitField; /* Specifies the data part of the global item. */
143} hidp_unknown_token, * phidp_unknown_token;
144
145typedef struct hid_pp_cap_ {
146 USAGE UsagePage;
147 UCHAR ReportID;
148 UCHAR BitPosition;
149 USHORT ReportSize; // WIN32 term for this is BitSize
150 USHORT ReportCount;
151 USHORT BytePosition;
152 USHORT BitCount;
153 ULONG BitField;
154 USHORT NextBytePosition;
155 USHORT LinkCollection;
156 USAGE LinkUsagePage;
157 USAGE LinkUsage;
158
159 // Start of 8 Flags in one byte
160 BOOLEAN IsMultipleItemsForArray:1;
161
162 BOOLEAN IsPadding:1;
163 BOOLEAN IsButtonCap:1;
164 BOOLEAN IsAbsolute:1;
165 BOOLEAN IsRange:1;
166 BOOLEAN IsAlias:1; // IsAlias is set to TRUE in the first n-1 capability structures added to the capability array. IsAlias set to FALSE in the nth capability structure.
167 BOOLEAN IsStringRange:1;
168 BOOLEAN IsDesignatorRange:1;
169 // End of 8 Flags in one byte
170 BOOLEAN Reserved1[3];
171
172 hidp_unknown_token UnknownTokens[4]; // 4 x 8 Byte
173
174 union {
175 struct {
176 USAGE UsageMin;
177 USAGE UsageMax;
178 USHORT StringMin;
179 USHORT StringMax;
180 USHORT DesignatorMin;
181 USHORT DesignatorMax;
182 USHORT DataIndexMin;
183 USHORT DataIndexMax;
184 } Range;
185 struct {
186 USAGE Usage;
187 USAGE Reserved1;
188 USHORT StringIndex;
189 USHORT Reserved2;
190 USHORT DesignatorIndex;
191 USHORT Reserved3;
192 USHORT DataIndex;
193 USHORT Reserved4;
194 } NotRange;
195 };
196 union {
197 struct {
198 LONG LogicalMin;
199 LONG LogicalMax;
200 } Button;
201 struct {
202 BOOLEAN HasNull;
203 UCHAR Reserved4[3];
204 LONG LogicalMin;
205 LONG LogicalMax;
206 LONG PhysicalMin;
207 LONG PhysicalMax;
208 } NotButton;
209 };
210 ULONG Units;
211 ULONG UnitsExp;
212
213} hid_pp_cap, *phid_pp_cap;
214
215typedef struct hidp_preparsed_data_ {
216 UCHAR MagicKey[8];
217 USAGE Usage;
218 USAGE UsagePage;
219 USHORT Reserved[2];
220
221 // CAPS structure for Input, Output and Feature
222 hid_pp_caps_info caps_info[3];
223
224 USHORT FirstByteOfLinkCollectionArray;
225 USHORT NumberLinkCollectionNodes;
226
227#ifndef _MSC_VER
228 // MINGW fails with: Flexible array member in union not supported
229 // Solution: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
230 union {
231#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
232#pragma GCC diagnostic push
233#pragma GCC diagnostic ignored "-Wpedantic"
234#endif
235 hid_pp_cap caps[0];
236 hid_pp_link_collection_node LinkCollectionArray[0];
237#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
238#pragma GCC diagnostic pop
239#endif
240 };
241#else
242 union {
243 hid_pp_cap caps[];
244 hid_pp_link_collection_node LinkCollectionArray[];
245 };
246#endif
247
248} hidp_preparsed_data;
249
250#ifdef _MSC_VER
251#pragma warning(pop)
252#endif
253
254#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidclass.h b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidclass.h
new file mode 100644
index 0000000..8acc52e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidclass.h
@@ -0,0 +1,40 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19
20#ifndef HIDAPI_HIDCLASS_H
21#define HIDAPI_HIDCLASS_H
22
23#ifdef HIDAPI_USE_DDK
24
25#include <hidclass.h>
26
27#else
28
29#include <winioctl.h>
30
31/* This part of the header mimics hidclass.h,
32 but only what is used by HIDAPI */
33
34#define HID_OUT_CTL_CODE(id) CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
35#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
36#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
37
38#endif
39
40#endif /* HIDAPI_HIDCLASS_H */
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidpi.h b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidpi.h
new file mode 100644
index 0000000..75a5812
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidpi.h
@@ -0,0 +1,72 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19
20#ifndef HIDAPI_HIDPI_H
21#define HIDAPI_HIDPI_H
22
23#ifdef HIDAPI_USE_DDK
24
25#include <hidpi.h>
26
27#else
28
29/* This part of the header mimics hidpi.h,
30 but only what is used by HIDAPI */
31
32typedef enum _HIDP_REPORT_TYPE
33{
34 HidP_Input,
35 HidP_Output,
36 HidP_Feature
37} HIDP_REPORT_TYPE;
38
39typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
40
41typedef struct _HIDP_CAPS
42{
43 USAGE Usage;
44 USAGE UsagePage;
45 USHORT InputReportByteLength;
46 USHORT OutputReportByteLength;
47 USHORT FeatureReportByteLength;
48 USHORT Reserved[17];
49
50 USHORT NumberLinkCollectionNodes;
51
52 USHORT NumberInputButtonCaps;
53 USHORT NumberInputValueCaps;
54 USHORT NumberInputDataIndices;
55
56 USHORT NumberOutputButtonCaps;
57 USHORT NumberOutputValueCaps;
58 USHORT NumberOutputDataIndices;
59
60 USHORT NumberFeatureButtonCaps;
61 USHORT NumberFeatureValueCaps;
62 USHORT NumberFeatureDataIndices;
63} HIDP_CAPS, *PHIDP_CAPS;
64
65#define HIDP_STATUS_SUCCESS 0x00110000
66#define HIDP_STATUS_INVALID_PREPARSED_DATA 0xc0110001
67
68typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, PHIDP_CAPS caps);
69
70#endif
71
72#endif /* HIDAPI_HIDPI_H */
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidsdi.h b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidsdi.h
new file mode 100644
index 0000000..95e2fcb
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_hidsdi.h
@@ -0,0 +1,59 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19
20#ifndef HIDAPI_HIDSDI_H
21#define HIDAPI_HIDSDI_H
22
23#ifdef HIDAPI_USE_DDK
24
25#include <hidsdi.h>
26
27#else
28
29/* This part of the header mimics hidsdi.h,
30 but only what is used by HIDAPI */
31
32typedef USHORT USAGE;
33
34#include "hidapi_hidpi.h"
35
36typedef struct _HIDD_ATTRIBUTES{
37 ULONG Size;
38 USHORT VendorID;
39 USHORT ProductID;
40 USHORT VersionNumber;
41} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
42
43typedef void (__stdcall *HidD_GetHidGuid_)(LPGUID hid_guid);
44typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
45typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
46typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
47typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
48typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
49typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
50typedef BOOLEAN (__stdcall *HidD_GetInputReport_)(HANDLE handle, PVOID data, ULONG length);
51typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
52typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
53typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
54typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers);
55typedef BOOLEAN (__stdcall *HidD_SetOutputReport_)(HANDLE HidDeviceObject, PVOID ReportBuffer, ULONG ReportBufferLength);
56
57#endif
58
59#endif /* HIDAPI_HIDSDI_H */
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_winapi.h b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_winapi.h
new file mode 100644
index 0000000..9c4b5c0
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidapi_winapi.h
@@ -0,0 +1,74 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 libusb/hidapi Team
6
7 Copyright 2022, All Rights Reserved.
8
9 At the discretion of the user of this library,
10 this software may be licensed under the terms of the
11 GNU General Public License v3, a BSD-Style license, or the
12 original HIDAPI license as outlined in the LICENSE.txt,
13 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
14 files located at the root of the source distribution.
15 These files may also be found in the public source
16 code repository located at:
17 https://github.com/libusb/hidapi .
18********************************************************/
19
20/** @file
21 * @defgroup API hidapi API
22 *
23 * Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
24 */
25
26#ifndef HIDAPI_WINAPI_H__
27#define HIDAPI_WINAPI_H__
28
29#include <stdint.h>
30
31#include <guiddef.h>
32
33#include "../hidapi/hidapi.h"
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39 /** @brief Get the container ID for a HID device.
40
41 Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
42
43 This function returns the `DEVPKEY_Device_ContainerId` property of
44 the given device. This can be used to correlate different
45 interfaces/ports on the same hardware device.
46
47 @ingroup API
48 @param dev A device handle returned from hid_open().
49 @param container_id The device's container ID on return.
50
51 @returns
52 This function returns 0 on success and -1 on error.
53 */
54 int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id);
55
56 /**
57 * @brief Reconstructs a HID Report Descriptor from a Win32 HIDP_PREPARSED_DATA structure.
58 * This reconstructed report descriptor is logical identical to the real report descriptor,
59 * but not byte wise identical.
60 *
61 * @param[in] hidp_preparsed_data Pointer to the HIDP_PREPARSED_DATA to read, i.e.: the value of PHIDP_PREPARSED_DATA,
62 * as returned by HidD_GetPreparsedData WinAPI function.
63 * @param buf Pointer to the buffer where the report descriptor should be stored.
64 * @param[in] buf_size Size of the buffer. The recommended size for the buffer is @ref HID_API_MAX_REPORT_DESCRIPTOR_SIZE bytes.
65 *
66 * @return Returns size of reconstructed report descriptor if successful, -1 for error.
67 */
68 int HID_API_EXPORT_CALL hid_winapi_descriptor_reconstruct_pp_data(void *hidp_preparsed_data, unsigned char *buf, size_t buf_size);
69
70#ifdef __cplusplus
71}
72#endif
73
74#endif
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcproj b/contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcproj
new file mode 100644
index 0000000..2918fc4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcproj
@@ -0,0 +1,196 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="9.00"
5 Name="hidtest"
6 ProjectGUID="{23E9FF6A-49D1-4993-B2B5-BBB992C6C712}"
7 RootNamespace="hidtest"
8 TargetFrameworkVersion="196613"
9 >
10 <Platforms>
11 <Platform
12 Name="Win32"
13 />
14 </Platforms>
15 <ToolFiles>
16 </ToolFiles>
17 <Configurations>
18 <Configuration
19 Name="Debug|Win32"
20 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
21 IntermediateDirectory="$(ConfigurationName)"
22 ConfigurationType="1"
23 CharacterSet="2"
24 >
25 <Tool
26 Name="VCPreBuildEventTool"
27 />
28 <Tool
29 Name="VCCustomBuildTool"
30 />
31 <Tool
32 Name="VCXMLDataGeneratorTool"
33 />
34 <Tool
35 Name="VCWebServiceProxyGeneratorTool"
36 />
37 <Tool
38 Name="VCMIDLTool"
39 />
40 <Tool
41 Name="VCCLCompilerTool"
42 Optimization="0"
43 AdditionalIncludeDirectories="..\hidapi;."
44 MinimalRebuild="true"
45 BasicRuntimeChecks="3"
46 RuntimeLibrary="3"
47 WarningLevel="3"
48 DebugInformationFormat="4"
49 />
50 <Tool
51 Name="VCManagedResourceCompilerTool"
52 />
53 <Tool
54 Name="VCResourceCompilerTool"
55 />
56 <Tool
57 Name="VCPreLinkEventTool"
58 />
59 <Tool
60 Name="VCLinkerTool"
61 AdditionalDependencies="hidapi.lib"
62 AdditionalLibraryDirectories="..\windows\Debug"
63 GenerateDebugInformation="true"
64 SubSystem="1"
65 TargetMachine="1"
66 />
67 <Tool
68 Name="VCALinkTool"
69 />
70 <Tool
71 Name="VCManifestTool"
72 />
73 <Tool
74 Name="VCXDCMakeTool"
75 />
76 <Tool
77 Name="VCBscMakeTool"
78 />
79 <Tool
80 Name="VCFxCopTool"
81 />
82 <Tool
83 Name="VCAppVerifierTool"
84 />
85 <Tool
86 Name="VCPostBuildEventTool"
87 Description="Copying hidapi.dll to the local directory."
88 CommandLine=""
89 />
90 </Configuration>
91 <Configuration
92 Name="Release|Win32"
93 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
94 IntermediateDirectory="$(ConfigurationName)"
95 ConfigurationType="1"
96 CharacterSet="2"
97 WholeProgramOptimization="1"
98 >
99 <Tool
100 Name="VCPreBuildEventTool"
101 />
102 <Tool
103 Name="VCCustomBuildTool"
104 />
105 <Tool
106 Name="VCXMLDataGeneratorTool"
107 />
108 <Tool
109 Name="VCWebServiceProxyGeneratorTool"
110 />
111 <Tool
112 Name="VCMIDLTool"
113 />
114 <Tool
115 Name="VCCLCompilerTool"
116 Optimization="2"
117 EnableIntrinsicFunctions="true"
118 AdditionalIncludeDirectories="..\hidapi;."
119 RuntimeLibrary="2"
120 EnableFunctionLevelLinking="true"
121 WarningLevel="3"
122 DebugInformationFormat="3"
123 />
124 <Tool
125 Name="VCManagedResourceCompilerTool"
126 />
127 <Tool
128 Name="VCResourceCompilerTool"
129 />
130 <Tool
131 Name="VCPreLinkEventTool"
132 />
133 <Tool
134 Name="VCLinkerTool"
135 AdditionalDependencies="hidapi.lib"
136 AdditionalLibraryDirectories="..\windows\Release"
137 GenerateDebugInformation="true"
138 SubSystem="1"
139 OptimizeReferences="2"
140 EnableCOMDATFolding="2"
141 TargetMachine="1"
142 />
143 <Tool
144 Name="VCALinkTool"
145 />
146 <Tool
147 Name="VCManifestTool"
148 />
149 <Tool
150 Name="VCXDCMakeTool"
151 />
152 <Tool
153 Name="VCBscMakeTool"
154 />
155 <Tool
156 Name="VCFxCopTool"
157 />
158 <Tool
159 Name="VCAppVerifierTool"
160 />
161 <Tool
162 Name="VCPostBuildEventTool"
163 Description="Copying hidapi.dll to the local directory."
164 CommandLine=""
165 />
166 </Configuration>
167 </Configurations>
168 <References>
169 </References>
170 <Files>
171 <Filter
172 Name="Source Files"
173 Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
174 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
175 >
176 <File
177 RelativePath="..\hidtest\test.c"
178 >
179 </File>
180 </Filter>
181 <Filter
182 Name="Header Files"
183 Filter="h;hpp;hxx;hm;inl;inc;xsd"
184 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
185 >
186 </Filter>
187 <Filter
188 Name="Resource Files"
189 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
190 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
191 >
192 </Filter>
193 </Files>
194 <Globals>
195 </Globals>
196</VisualStudioProject>
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcxproj b/contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcxproj
new file mode 100644
index 0000000..a468d8b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/hidtest.vcxproj
@@ -0,0 +1,176 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <ItemGroup Label="ProjectConfigurations">
4 <ProjectConfiguration Include="Debug|Win32">
5 <Configuration>Debug</Configuration>
6 <Platform>Win32</Platform>
7 </ProjectConfiguration>
8 <ProjectConfiguration Include="Debug|x64">
9 <Configuration>Debug</Configuration>
10 <Platform>x64</Platform>
11 </ProjectConfiguration>
12 <ProjectConfiguration Include="Release|Win32">
13 <Configuration>Release</Configuration>
14 <Platform>Win32</Platform>
15 </ProjectConfiguration>
16 <ProjectConfiguration Include="Release|x64">
17 <Configuration>Release</Configuration>
18 <Platform>x64</Platform>
19 </ProjectConfiguration>
20 </ItemGroup>
21 <PropertyGroup Label="Globals">
22 <ProjectGuid>{23E9FF6A-49D1-4993-B2B5-BBB992C6C712}</ProjectGuid>
23 <RootNamespace>hidtest</RootNamespace>
24 </PropertyGroup>
25 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
26 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
27 <ConfigurationType>Application</ConfigurationType>
28 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
29 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
30 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
31 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
32 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
33 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
34 <CharacterSet>MultiByte</CharacterSet>
35 <WholeProgramOptimization>true</WholeProgramOptimization>
36 </PropertyGroup>
37 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
38 <ConfigurationType>Application</ConfigurationType>
39 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
40 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
41 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
42 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
43 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
44 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
45 <CharacterSet>MultiByte</CharacterSet>
46 <WholeProgramOptimization>true</WholeProgramOptimization>
47 </PropertyGroup>
48 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
49 <ConfigurationType>Application</ConfigurationType>
50 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
51 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
52 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
53 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
54 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
55 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
56 <CharacterSet>MultiByte</CharacterSet>
57 </PropertyGroup>
58 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
59 <ConfigurationType>Application</ConfigurationType>
60 <PlatformToolset Condition="'$(VisualStudioVersion)'=='11'">v110</PlatformToolset>
61 <PlatformToolset Condition="'$(VisualStudioVersion)'=='12'">v120</PlatformToolset>
62 <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
63 <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
64 <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
65 <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
66 <CharacterSet>MultiByte</CharacterSet>
67 </PropertyGroup>
68 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
69 <ImportGroup Label="ExtensionSettings">
70 </ImportGroup>
71 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
72 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
73 </ImportGroup>
74 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
75 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
76 </ImportGroup>
77 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
78 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
79 </ImportGroup>
80 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
81 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
82 </ImportGroup>
83 <PropertyGroup Label="UserMacros" />
84 <PropertyGroup>
85 <_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
86 </PropertyGroup>
87 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
88 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
89 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
90 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
91 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
92 <ClCompile>
93 <Optimization>Disabled</Optimization>
94 <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
95 <MinimalRebuild>true</MinimalRebuild>
96 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
97 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
98 <WarningLevel>Level3</WarningLevel>
99 <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
100 </ClCompile>
101 <Link>
102 <AdditionalDependencies>hidapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
103 <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
104 <GenerateDebugInformation>true</GenerateDebugInformation>
105 <SubSystem>Console</SubSystem>
106 <TargetMachine>MachineX86</TargetMachine>
107 </Link>
108 </ItemDefinitionGroup>
109 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
110 <ClCompile>
111 <Optimization>Disabled</Optimization>
112 <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
113 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
114 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
115 <WarningLevel>Level3</WarningLevel>
116 <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
117 </ClCompile>
118 <Link>
119 <AdditionalDependencies>hidapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
120 <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
121 <GenerateDebugInformation>true</GenerateDebugInformation>
122 <SubSystem>Console</SubSystem>
123 </Link>
124 </ItemDefinitionGroup>
125 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
126 <ClCompile>
127 <Optimization>MaxSpeed</Optimization>
128 <IntrinsicFunctions>true</IntrinsicFunctions>
129 <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
130 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
131 <FunctionLevelLinking>true</FunctionLevelLinking>
132 <WarningLevel>Level3</WarningLevel>
133 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
134 </ClCompile>
135 <Link>
136 <AdditionalDependencies>hidapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
137 <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
138 <GenerateDebugInformation>true</GenerateDebugInformation>
139 <SubSystem>Console</SubSystem>
140 <OptimizeReferences>true</OptimizeReferences>
141 <EnableCOMDATFolding>true</EnableCOMDATFolding>
142 <TargetMachine>MachineX86</TargetMachine>
143 </Link>
144 </ItemDefinitionGroup>
145 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
146 <ClCompile>
147 <Optimization>MaxSpeed</Optimization>
148 <IntrinsicFunctions>true</IntrinsicFunctions>
149 <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
150 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
151 <FunctionLevelLinking>true</FunctionLevelLinking>
152 <WarningLevel>Level3</WarningLevel>
153 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
154 </ClCompile>
155 <Link>
156 <AdditionalDependencies>hidapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
157 <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
158 <GenerateDebugInformation>true</GenerateDebugInformation>
159 <SubSystem>Console</SubSystem>
160 <OptimizeReferences>true</OptimizeReferences>
161 <EnableCOMDATFolding>true</EnableCOMDATFolding>
162 </Link>
163 </ItemDefinitionGroup>
164 <ItemGroup>
165 <ClCompile Include="..\hidtest\test.c" />
166 </ItemGroup>
167 <ItemGroup>
168 <ProjectReference Include="hidapi.vcxproj">
169 <Project>{a107c21c-418a-4697-bb10-20c3aa60e2e4}</Project>
170 <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
171 </ProjectReference>
172 </ItemGroup>
173 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
174 <ImportGroup Label="ExtensionTargets">
175 </ImportGroup>
176</Project>
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/CMakeLists.txt
new file mode 100644
index 0000000..f017de9
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/CMakeLists.txt
@@ -0,0 +1,15 @@
1project(pp_data_dump C)
2
3add_executable(pp_data_dump pp_data_dump.c)
4set_target_properties(pp_data_dump
5 PROPERTIES
6 C_STANDARD 11
7 C_STANDARD_REQUIRED TRUE
8)
9target_link_libraries(pp_data_dump
10 PRIVATE hidapi_winapi
11)
12
13install(TARGETS pp_data_dump
14 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
15)
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/README.md b/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/README.md
new file mode 100644
index 0000000..a0989cd
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/README.md
@@ -0,0 +1,122 @@
1## pp_data_dump.exe for Windows
2
3
4pp_data_dump.exe is a small command line tool for Windows, which dumps the content of the [Preparsed Data](https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/preparsed-data) structure, provided by the Windows HID subsystem, into a file.
5
6The generated file is in a text format, which is readable for human, as by the hid_report_reconstructor_test.exe unit test executable of the HIDAPI project. This unit test allows it to test the HIDAPIs report descriptor reconstructor - offline, without the hardware device connected.
7
8pp_data_dump.exe has no arguments, just connect you HID device and execute pp_data_dump.exe. It will generate one file with the name
9```
10<vendor_id>_<product_id>_<usage>_<usage_table>.pp_data
11```
12for each top-level collection, of each connected HID device.
13
14
15## File content
16
17The content of such a .pp_data file looks like the struct, which HIDAPI uses internally to represent the Preparsed Data.
18
19*NOTE:
20Windows parses HID report descriptors into opaque `_HIDP_PREPARSED_DATA` objects.
21The internal structure of `_HIDP_PREPARSED_DATA` is reserved for internal system use.\
22Microsoft doesn't document this structure. [hid_preparsed_data.cc](https://chromium.googlesource.com/chromium/src/+/73fdaaf605bb60caf34d5f30bb84a417688aa528/services/device/hid/hid_preparsed_data.cc) is taken as a reference for its parsing.*
23
24```
25# HIDAPI device info struct:
26dev->vendor_id = 0x046D
27dev->product_id = 0xB010
28dev->manufacturer_string = "Logitech"
29dev->product_string = "Logitech Bluetooth Wireless Mouse"
30dev->release_number = 0x0000
31dev->interface_number = -1
32dev->usage = 0x0001
33dev->usage_page = 0x000C
34dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col02#8&1cf1c1b9&3&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
35
36# Preparsed Data struct:
37pp_data->MagicKey = 0x48696450204B4452
38pp_data->Usage = 0x0001
39pp_data->UsagePage = 0x000C
40pp_data->Reserved = 0x00000000
41# Input caps_info struct:
42pp_data->caps_info[0]->FirstCap = 0
43pp_data->caps_info[0]->LastCap = 1
44pp_data->caps_info[0]->NumberOfCaps = 1
45pp_data->caps_info[0]->ReportByteLength = 2
46# Output caps_info struct:
47pp_data->caps_info[1]->FirstCap = 1
48pp_data->caps_info[1]->LastCap = 1
49pp_data->caps_info[1]->NumberOfCaps = 0
50pp_data->caps_info[1]->ReportByteLength = 0
51# Feature caps_info struct:
52pp_data->caps_info[2]->FirstCap = 1
53pp_data->caps_info[2]->LastCap = 1
54pp_data->caps_info[2]->NumberOfCaps = 0
55pp_data->caps_info[2]->ReportByteLength = 0
56# LinkCollectionArray Offset & Size:
57pp_data->FirstByteOfLinkCollectionArray = 0x0068
58pp_data->NumberLinkCollectionNodes = 1
59# Input hid_pp_cap struct:
60pp_data->cap[0]->UsagePage = 0x0006
61pp_data->cap[0]->ReportID = 0x03
62pp_data->cap[0]->BitPosition = 0
63pp_data->cap[0]->BitSize = 8
64pp_data->cap[0]->ReportCount = 1
65pp_data->cap[0]->BytePosition = 0x0001
66pp_data->cap[0]->BitCount = 8
67pp_data->cap[0]->BitField = 0x02
68pp_data->cap[0]->NextBytePosition = 0x0002
69pp_data->cap[0]->LinkCollection = 0x0000
70pp_data->cap[0]->LinkUsagePage = 0x000C
71pp_data->cap[0]->LinkUsage = 0x0001
72pp_data->cap[0]->IsMultipleItemsForArray = 0
73pp_data->cap[0]->IsButtonCap = 0
74pp_data->cap[0]->IsPadding = 0
75pp_data->cap[0]->IsAbsolute = 1
76pp_data->cap[0]->IsRange = 0
77pp_data->cap[0]->IsAlias = 0
78pp_data->cap[0]->IsStringRange = 0
79pp_data->cap[0]->IsDesignatorRange = 0
80pp_data->cap[0]->Reserved1 = 0x000000
81pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
82pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
83pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
84pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
85pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
86pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
87pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
88pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
89pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
90pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
91pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
92pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
93pp_data->cap[0]->NotRange.Usage = 0x0020
94pp_data->cap[0]->NotRange.Reserved1 = 0x0020
95pp_data->cap[0]->NotRange.StringIndex = 0
96pp_data->cap[0]->NotRange.Reserved2 = 0
97pp_data->cap[0]->NotRange.DesignatorIndex = 0
98pp_data->cap[0]->NotRange.Reserved3 = 0
99pp_data->cap[0]->NotRange.DataIndex = 0
100pp_data->cap[0]->NotRange.Reserved4 = 0
101pp_data->cap[0]->NotButton.HasNull = 0
102pp_data->cap[0]->NotButton.Reserved4 = 0x000000
103pp_data->cap[0]->NotButton.LogicalMin = 0
104pp_data->cap[0]->NotButton.LogicalMax = 100
105pp_data->cap[0]->NotButton.PhysicalMin = 0
106pp_data->cap[0]->NotButton.PhysicalMax = 0
107pp_data->cap[0]->Units = 0
108pp_data->cap[0]->UnitsExp = 0
109
110# Output hid_pp_cap struct:
111# Feature hid_pp_cap struct:
112# Link Collections:
113pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
114pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
115pp_data->LinkCollectionArray[0]->Parent = 0
116pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
117pp_data->LinkCollectionArray[0]->NextSibling = 0
118pp_data->LinkCollectionArray[0]->FirstChild = 0
119pp_data->LinkCollectionArray[0]->CollectionType = 1
120pp_data->LinkCollectionArray[0]->IsAlias = 0
121pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
122``` \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/pp_data_dump.c b/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/pp_data_dump.c
new file mode 100644
index 0000000..d5df68b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/pp_data_dump/pp_data_dump.c
@@ -0,0 +1,238 @@
1#if defined(__MINGW32__)
2 // Needed for %hh
3 #define __USE_MINGW_ANSI_STDIO 1
4#endif
5
6#include <hid.c>
7#include <../windows/hidapi_descriptor_reconstruct.h>
8
9#include <hidapi.h>
10
11void dump_hid_pp_cap(FILE* file, phid_pp_cap pp_cap, unsigned int cap_idx) {
12 fprintf(file, "pp_data->cap[%u]->UsagePage = 0x%04hX\n", cap_idx, pp_cap->UsagePage);
13 fprintf(file, "pp_data->cap[%u]->ReportID = 0x%02hhX\n", cap_idx, pp_cap->ReportID);
14 fprintf(file, "pp_data->cap[%u]->BitPosition = %hhu\n", cap_idx, pp_cap->BitPosition);
15 fprintf(file, "pp_data->cap[%u]->BitSize = %hu\n", cap_idx, pp_cap->ReportSize);
16 fprintf(file, "pp_data->cap[%u]->ReportCount = %hu\n", cap_idx, pp_cap->ReportCount);
17 fprintf(file, "pp_data->cap[%u]->BytePosition = 0x%04hX\n", cap_idx, pp_cap->BytePosition);
18 fprintf(file, "pp_data->cap[%u]->BitCount = %hu\n", cap_idx, pp_cap->BitCount);
19 fprintf(file, "pp_data->cap[%u]->BitField = 0x%02lX\n", cap_idx, pp_cap->BitField);
20 fprintf(file, "pp_data->cap[%u]->NextBytePosition = 0x%04hX\n", cap_idx, pp_cap->NextBytePosition);
21 fprintf(file, "pp_data->cap[%u]->LinkCollection = 0x%04hX\n", cap_idx, pp_cap->LinkCollection);
22 fprintf(file, "pp_data->cap[%u]->LinkUsagePage = 0x%04hX\n", cap_idx, pp_cap->LinkUsagePage);
23 fprintf(file, "pp_data->cap[%u]->LinkUsage = 0x%04hX\n", cap_idx, pp_cap->LinkUsage);
24
25 // 8 Flags in one byte
26 fprintf(file, "pp_data->cap[%u]->IsMultipleItemsForArray = %hhu\n", cap_idx, pp_cap->IsMultipleItemsForArray);
27 fprintf(file, "pp_data->cap[%u]->IsButtonCap = %hhu\n", cap_idx, pp_cap->IsButtonCap);
28 fprintf(file, "pp_data->cap[%u]->IsPadding = %hhu\n", cap_idx, pp_cap->IsPadding);
29 fprintf(file, "pp_data->cap[%u]->IsAbsolute = %hhu\n", cap_idx, pp_cap->IsAbsolute);
30 fprintf(file, "pp_data->cap[%u]->IsRange = %hhu\n", cap_idx, pp_cap->IsRange);
31 fprintf(file, "pp_data->cap[%u]->IsAlias = %hhu\n", cap_idx, pp_cap->IsAlias);
32 fprintf(file, "pp_data->cap[%u]->IsStringRange = %hhu\n", cap_idx, pp_cap->IsStringRange);
33 fprintf(file, "pp_data->cap[%u]->IsDesignatorRange = %hhu\n", cap_idx, pp_cap->IsDesignatorRange);
34
35 fprintf(file, "pp_data->cap[%u]->Reserved1 = 0x%02hhX%02hhX%02hhX\n", cap_idx, pp_cap->Reserved1[0], pp_cap->Reserved1[1], pp_cap->Reserved1[2]);
36
37 for (int token_idx = 0; token_idx < 4; token_idx++) {
38 fprintf(file, "pp_data->cap[%u]->pp_cap->UnknownTokens[%d].Token = 0x%02hhX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].Token);
39 fprintf(file, "pp_data->cap[%u]->pp_cap->UnknownTokens[%d].Reserved = 0x%02hhX%02hhX%02hhX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].Reserved[0], pp_cap->UnknownTokens[token_idx].Reserved[1], pp_cap->UnknownTokens[token_idx].Reserved[2]);
40 fprintf(file, "pp_data->cap[%u]->pp_cap->UnknownTokens[%d].BitField = 0x%08lX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].BitField);
41 }
42
43 if (pp_cap->IsRange) {
44 fprintf(file, "pp_data->cap[%u]->Range.UsageMin = 0x%04hX\n", cap_idx, pp_cap->Range.UsageMin);
45 fprintf(file, "pp_data->cap[%u]->Range.UsageMax = 0x%04hX\n", cap_idx, pp_cap->Range.UsageMax);
46 fprintf(file, "pp_data->cap[%u]->Range.StringMin = %hu\n", cap_idx, pp_cap->Range.StringMin);
47 fprintf(file, "pp_data->cap[%u]->Range.StringMax = %hu\n", cap_idx, pp_cap->Range.StringMax);
48 fprintf(file, "pp_data->cap[%u]->Range.DesignatorMin = %hu\n", cap_idx, pp_cap->Range.DesignatorMin);
49 fprintf(file, "pp_data->cap[%u]->Range.DesignatorMax = %hu\n", cap_idx, pp_cap->Range.DesignatorMax);
50 fprintf(file, "pp_data->cap[%u]->Range.DataIndexMin = %hu\n", cap_idx, pp_cap->Range.DataIndexMin);
51 fprintf(file, "pp_data->cap[%u]->Range.DataIndexMax = %hu\n", cap_idx, pp_cap->Range.DataIndexMax);
52 }
53 else {
54 fprintf(file, "pp_data->cap[%u]->NotRange.Usage = 0x%04hX\n", cap_idx, pp_cap->NotRange.Usage);
55 fprintf(file, "pp_data->cap[%u]->NotRange.Reserved1 = 0x%04hX\n", cap_idx, pp_cap->NotRange.Reserved1);
56 fprintf(file, "pp_data->cap[%u]->NotRange.StringIndex = %hu\n", cap_idx, pp_cap->NotRange.StringIndex);
57 fprintf(file, "pp_data->cap[%u]->NotRange.Reserved2 = %hu\n", cap_idx, pp_cap->NotRange.Reserved2);
58 fprintf(file, "pp_data->cap[%u]->NotRange.DesignatorIndex = %hu\n", cap_idx, pp_cap->NotRange.DesignatorIndex);
59 fprintf(file, "pp_data->cap[%u]->NotRange.Reserved3 = %hu\n", cap_idx, pp_cap->NotRange.Reserved3);
60 fprintf(file, "pp_data->cap[%u]->NotRange.DataIndex = %hu\n", cap_idx, pp_cap->NotRange.DataIndex);
61 fprintf(file, "pp_data->cap[%u]->NotRange.Reserved4 = %hu\n", cap_idx, pp_cap->NotRange.Reserved4);
62 }
63
64 if (pp_cap->IsButtonCap) {
65 fprintf(file, "pp_data->cap[%u]->Button.LogicalMin = %ld\n", cap_idx, pp_cap->Button.LogicalMin);
66 fprintf(file, "pp_data->cap[%u]->Button.LogicalMax = %ld\n", cap_idx, pp_cap->Button.LogicalMax);
67 }
68 else
69 {
70 fprintf(file, "pp_data->cap[%u]->NotButton.HasNull = %hhu\n", cap_idx, pp_cap->NotButton.HasNull);
71 fprintf(file, "pp_data->cap[%u]->NotButton.Reserved4 = 0x%02hhX%02hhX%02hhX\n", cap_idx, pp_cap->NotButton.Reserved4[0], pp_cap->NotButton.Reserved4[1], pp_cap->NotButton.Reserved4[2]);
72 fprintf(file, "pp_data->cap[%u]->NotButton.LogicalMin = %ld\n", cap_idx, pp_cap->NotButton.LogicalMin);
73 fprintf(file, "pp_data->cap[%u]->NotButton.LogicalMax = %ld\n", cap_idx, pp_cap->NotButton.LogicalMax);
74 fprintf(file, "pp_data->cap[%u]->NotButton.PhysicalMin = %ld\n", cap_idx, pp_cap->NotButton.PhysicalMin);
75 fprintf(file, "pp_data->cap[%u]->NotButton.PhysicalMax = %ld\n", cap_idx, pp_cap->NotButton.PhysicalMax);
76 };
77 fprintf(file, "pp_data->cap[%u]->Units = %lu\n", cap_idx, pp_cap->Units);
78 fprintf(file, "pp_data->cap[%u]->UnitsExp = %lu\n", cap_idx, pp_cap->UnitsExp);
79}
80
81void dump_hidp_link_collection_node(FILE* file, phid_pp_link_collection_node pcoll, unsigned int coll_idx) {
82 fprintf(file, "pp_data->LinkCollectionArray[%u]->LinkUsage = 0x%04hX\n", coll_idx, pcoll->LinkUsage);
83 fprintf(file, "pp_data->LinkCollectionArray[%u]->LinkUsagePage = 0x%04hX\n", coll_idx, pcoll->LinkUsagePage);
84 fprintf(file, "pp_data->LinkCollectionArray[%u]->Parent = %hu\n", coll_idx, pcoll->Parent);
85 fprintf(file, "pp_data->LinkCollectionArray[%u]->NumberOfChildren = %hu\n", coll_idx, pcoll->NumberOfChildren);
86 fprintf(file, "pp_data->LinkCollectionArray[%u]->NextSibling = %hu\n", coll_idx, pcoll->NextSibling);
87 fprintf(file, "pp_data->LinkCollectionArray[%u]->FirstChild = %hu\n", coll_idx, pcoll->FirstChild);
88 // The compilers are not consistent on ULONG-bit-fields: They lose the unsinged or define them as int.
89 // Thus just always cast them to unsinged int, which should be fine, as the biggest bit-field is 28 bit
90 fprintf(file, "pp_data->LinkCollectionArray[%u]->CollectionType = %u\n", coll_idx, (unsigned int)(pcoll->CollectionType));
91 fprintf(file, "pp_data->LinkCollectionArray[%u]->IsAlias = %u\n", coll_idx, (unsigned int)(pcoll->IsAlias));
92 fprintf(file, "pp_data->LinkCollectionArray[%u]->Reserved = 0x%08X\n", coll_idx, (unsigned int)(pcoll->Reserved));
93}
94
95int dump_pp_data(FILE* file, hid_device* dev)
96{
97 BOOL res;
98 hidp_preparsed_data* pp_data = NULL;
99
100 res = HidD_GetPreparsedData(dev->device_handle, (PHIDP_PREPARSED_DATA*) &pp_data);
101 if (!res) {
102 printf("ERROR: HidD_GetPreparsedData failed!");
103 return -1;
104 }
105 else {
106 fprintf(file, "pp_data->MagicKey = 0x%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX\n", pp_data->MagicKey[0], pp_data->MagicKey[1], pp_data->MagicKey[2], pp_data->MagicKey[3], pp_data->MagicKey[4], pp_data->MagicKey[5], pp_data->MagicKey[6], pp_data->MagicKey[7]);
107 fprintf(file, "pp_data->Usage = 0x%04hX\n", pp_data->Usage);
108 fprintf(file, "pp_data->UsagePage = 0x%04hX\n", pp_data->UsagePage);
109 fprintf(file, "pp_data->Reserved = 0x%04hX%04hX\n", pp_data->Reserved[0], pp_data->Reserved[1]);
110 fprintf(file, "# Input caps_info struct:\n");
111 fprintf(file, "pp_data->caps_info[0]->FirstCap = %hu\n", pp_data->caps_info[0].FirstCap);
112 fprintf(file, "pp_data->caps_info[0]->LastCap = %hu\n", pp_data->caps_info[0].LastCap);
113 fprintf(file, "pp_data->caps_info[0]->NumberOfCaps = %hu\n", pp_data->caps_info[0].NumberOfCaps);
114 fprintf(file, "pp_data->caps_info[0]->ReportByteLength = %hu\n", pp_data->caps_info[0].ReportByteLength);
115 fprintf(file, "# Output caps_info struct:\n");
116 fprintf(file, "pp_data->caps_info[1]->FirstCap = %hu\n", pp_data->caps_info[1].FirstCap);
117 fprintf(file, "pp_data->caps_info[1]->LastCap = %hu\n", pp_data->caps_info[1].LastCap);
118 fprintf(file, "pp_data->caps_info[1]->NumberOfCaps = %hu\n", pp_data->caps_info[1].NumberOfCaps);
119 fprintf(file, "pp_data->caps_info[1]->ReportByteLength = %hu\n", pp_data->caps_info[1].ReportByteLength);
120 fprintf(file, "# Feature caps_info struct:\n");
121 fprintf(file, "pp_data->caps_info[2]->FirstCap = %hu\n", pp_data->caps_info[2].FirstCap);
122 fprintf(file, "pp_data->caps_info[2]->LastCap = %hu\n", pp_data->caps_info[2].LastCap);
123 fprintf(file, "pp_data->caps_info[2]->NumberOfCaps = %hu\n", pp_data->caps_info[2].NumberOfCaps);
124 fprintf(file, "pp_data->caps_info[2]->ReportByteLength = %hu\n", pp_data->caps_info[2].ReportByteLength);
125 fprintf(file, "# LinkCollectionArray Offset & Size:\n");
126 fprintf(file, "pp_data->FirstByteOfLinkCollectionArray = 0x%04hX\n", pp_data->FirstByteOfLinkCollectionArray);
127 fprintf(file, "pp_data->NumberLinkCollectionNodes = %hu\n", pp_data->NumberLinkCollectionNodes);
128
129
130 phid_pp_cap pcap = (phid_pp_cap)(((unsigned char*)pp_data) + offsetof(hidp_preparsed_data, caps));
131 fprintf(file, "# Input hid_pp_cap struct:\n");
132 for (int caps_idx = pp_data->caps_info[0].FirstCap; caps_idx < pp_data->caps_info[0].LastCap; caps_idx++) {
133 dump_hid_pp_cap(file, pcap + caps_idx, caps_idx);
134 fprintf(file, "\n");
135 }
136 fprintf(file, "# Output hid_pp_cap struct:\n");
137 for (int caps_idx = pp_data->caps_info[1].FirstCap; caps_idx < pp_data->caps_info[1].LastCap; caps_idx++) {
138 dump_hid_pp_cap(file, pcap + caps_idx, caps_idx);
139 fprintf(file, "\n");
140 }
141 fprintf(file, "# Feature hid_pp_cap struct:\n");
142 for (int caps_idx = pp_data->caps_info[2].FirstCap; caps_idx < pp_data->caps_info[2].LastCap; caps_idx++) {
143 dump_hid_pp_cap(file, pcap + caps_idx, caps_idx);
144 fprintf(file, "\n");
145 }
146
147 phid_pp_link_collection_node pcoll = (phid_pp_link_collection_node)(((unsigned char*)pcap) + pp_data->FirstByteOfLinkCollectionArray);
148 fprintf(file, "# Link Collections:\n");
149 for (int coll_idx = 0; coll_idx < pp_data->NumberLinkCollectionNodes; coll_idx++) {
150 dump_hidp_link_collection_node(file, pcoll + coll_idx, coll_idx);
151 }
152
153 HidD_FreePreparsedData((PHIDP_PREPARSED_DATA) pp_data);
154 return 0;
155 }
156}
157
158int main(int argc, char* argv[])
159{
160 (void)argc;
161 (void)argv;
162
163 #define MAX_STR 255
164
165 struct hid_device_info *devs, *cur_dev;
166
167 printf("pp_data_dump tool. Compiled with hidapi version %s, runtime version %s.\n", HID_API_VERSION_STR, hid_version_str());
168 if (hid_version()->major == HID_API_VERSION_MAJOR && hid_version()->minor == HID_API_VERSION_MINOR && hid_version()->patch == HID_API_VERSION_PATCH) {
169 printf("Compile-time version matches runtime version of hidapi.\n\n");
170 }
171 else {
172 printf("Compile-time version is different than runtime version of hidapi.\n]n");
173 }
174
175 if (hid_init())
176 return -1;
177
178 devs = hid_enumerate(0x0, 0x0);
179 cur_dev = devs;
180 while (cur_dev) {
181 printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
182 printf("\n");
183 printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
184 printf(" Product: %ls\n", cur_dev->product_string);
185 printf(" Release: %hX\n", cur_dev->release_number);
186 printf(" Interface: %d\n", cur_dev->interface_number);
187 printf(" Usage (page): %02X (%02X)\n", cur_dev->usage, cur_dev->usage_page);
188
189 hid_device *device = hid_open_path(cur_dev->path);
190 if (device) {
191 char filename[MAX_STR];
192 FILE* file;
193
194 sprintf_s(filename, MAX_STR, "%04X_%04X_%04X_%04X.pp_data", cur_dev->vendor_id, cur_dev->product_id, cur_dev->usage, cur_dev->usage_page);
195 errno_t err = fopen_s(&file, filename, "w");
196 if (err == 0) {
197 fprintf(file, "# HIDAPI device info struct:\n");
198 fprintf(file, "dev->vendor_id = 0x%04hX\n", cur_dev->vendor_id);
199 fprintf(file, "dev->product_id = 0x%04hX\n", cur_dev->product_id);
200 fprintf(file, "dev->manufacturer_string = \"%ls\"\n", cur_dev->manufacturer_string);
201 fprintf(file, "dev->product_string = \"%ls\"\n", cur_dev->product_string);
202 fprintf(file, "dev->release_number = 0x%04hX\n", cur_dev->release_number);
203 fprintf(file, "dev->interface_number = %d\n", cur_dev->interface_number);
204 fprintf(file, "dev->usage = 0x%04hX\n", cur_dev->usage);
205 fprintf(file, "dev->usage_page = 0x%04hX\n", cur_dev->usage_page);
206 fprintf(file, "dev->path = \"%s\"\n", cur_dev->path);
207 fprintf(file, "\n# Preparsed Data struct:\n");
208 int res = dump_pp_data(file, device);
209
210 if (res == 0) {
211 printf("Dumped Preparsed Data to %s\n", filename);
212 }
213 else {
214 printf("ERROR: Dump Preparsed Data to %s failed!\n", filename);
215 }
216
217 fclose(file);
218 }
219
220 hid_close(device);
221 }
222 else {
223 printf(" Device: not available.\n");
224 }
225
226 printf("\n");
227 cur_dev = cur_dev->next;
228 }
229 hid_free_enumeration(devs);
230
231
232 /* Free static HIDAPI objects. */
233 hid_exit();
234
235 //system("pause");
236
237 return 0;
238}
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/CMakeLists.txt b/contrib/SDL-3.2.8/src/hidapi/windows/test/CMakeLists.txt
new file mode 100644
index 0000000..eae3217
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/CMakeLists.txt
@@ -0,0 +1,76 @@
1add_executable(hid_report_reconstructor_test hid_report_reconstructor_test.c)
2set_target_properties(hid_report_reconstructor_test
3 PROPERTIES
4 C_STANDARD 11
5 C_STANDARD_REQUIRED TRUE
6)
7
8target_link_libraries(hid_report_reconstructor_test
9 PRIVATE hidapi_include hidapi_winapi
10)
11
12# Each test case requires 2 files:
13# <name>.pp_data - textual representation of HIDP_PREPARSED_DATA;
14# <name>_expected.rpt_desc - reconstructed HID Report Descriptor out of .pp_data file;
15#
16# (Non-required by test):
17# <name>_real.dpt_desc - the original report rescriptor used to create a test case;
18set(HID_DESCRIPTOR_RECONSTRUCT_TEST_CASES
19 046D_C52F_0001_000C
20 046D_C52F_0001_FF00
21 046D_C52F_0002_0001
22 046D_C52F_0002_FF00
23 17CC_1130_0000_FF01
24 046D_0A37_0001_000C
25 046A_0011_0006_0001
26 046D_C077_0002_0001
27 046D_C283_0004_0001
28 046D_B010_0006_0001
29 046D_B010_0002_FF00
30 046D_B010_0002_0001
31 046D_B010_0001_FF00
32 046D_B010_0001_000C
33 046D_C534_0001_000C
34 046D_C534_0001_FF00
35 046D_C534_0002_0001
36 046D_C534_0002_FF00
37 046D_C534_0006_0001
38 046D_C534_0080_0001
39 047F_C056_0001_000C
40 047F_C056_0003_FFA0
41 047F_C056_0005_000B
42 045E_02FF_0005_0001
43)
44
45set(CMAKE_VERSION_SUPPORTS_ENVIRONMENT_MODIFICATION "3.22")
46
47if(HIDAPI_ENABLE_ASAN AND MSVC)
48 if(CMAKE_VERSION VERSION_LESS CMAKE_VERSION_SUPPORTS_ENVIRONMENT_MODIFICATION)
49 message("CTest/ASAN: Make sure to run ctest from MSVC Command Prompt")
50 endif()
51endif()
52
53foreach(TEST_CASE ${HID_DESCRIPTOR_RECONSTRUCT_TEST_CASES})
54 set(TEST_PP_DATA "${CMAKE_CURRENT_LIST_DIR}/data/${TEST_CASE}.pp_data")
55 if(NOT EXISTS "${TEST_PP_DATA}")
56 message(FATAL_ERROR "Missing '${TEST_PP_DATA}' file for '${TEST_CASE}' test case")
57 endif()
58 set(TEST_EXPECTED_DESCRIPTOR "${CMAKE_CURRENT_LIST_DIR}/data/${TEST_CASE}_expected.rpt_desc")
59 if(NOT EXISTS "${TEST_EXPECTED_DESCRIPTOR}")
60 message(FATAL_ERROR "Missing '${TEST_EXPECTED_DESCRIPTOR}' file for '${TEST_CASE}' test case")
61 endif()
62
63 add_test(NAME "WinHidReportReconstructTest_${TEST_CASE}"
64 COMMAND hid_report_reconstructor_test "${TEST_PP_DATA}" "${TEST_EXPECTED_DESCRIPTOR}"
65 WORKING_DIRECTORY "$<TARGET_FILE_DIR:hidapi_winapi>"
66 )
67 if(HIDAPI_ENABLE_ASAN)
68 if(MSVC)
69 if(NOT CMAKE_VERSION VERSION_LESS CMAKE_VERSION_SUPPORTS_ENVIRONMENT_MODIFICATION)
70 get_filename_component(MSVC_BUILD_TOOLS_DIR "${CMAKE_LINKER}" DIRECTORY)
71 set_property(TEST "WinHidReportReconstructTest_${TEST_CASE}" PROPERTY ENVIRONMENT_MODIFICATION "PATH=path_list_append:${MSVC_BUILD_TOOLS_DIR}")
72 endif()
73 endif()
74 set_property(TEST "WinHidReportReconstructTest_${TEST_CASE}" PROPERTY ENVIRONMENT "ASAN_SAVE_DUMPS=AsanDump_${TEST_CASE}.dmp")
75 endif()
76endforeach()
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001.pp_data
new file mode 100644
index 0000000..6226996
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001.pp_data
@@ -0,0 +1,420 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x045E
3dev->product_id = 0x02FF
4dev->manufacturer_string = ""
5dev->product_string = "Controller (Xbox One For Windows)"
6dev->release_number = 0x0000
7dev->interface_number = -1
8dev->usage = 0x0005
9dev->usage_page = 0x0001
10dev->path = "\\?\HID#VID_045E&PID_02FF&IG_00#7&5ea4a81&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0005
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 7
20pp_data->caps_info[0]->NumberOfCaps = 7
21pp_data->caps_info[0]->ReportByteLength = 16
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 7
24pp_data->caps_info[1]->LastCap = 7
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 7
29pp_data->caps_info[2]->LastCap = 7
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x02D8
34pp_data->NumberLinkCollectionNodes = 4
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0001
37pp_data->cap[0]->ReportID = 0x00
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 16
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0003
42pp_data->cap[0]->BitCount = 16
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0005
45pp_data->cap[0]->LinkCollection = 0x0001
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0000
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 0
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0031
70pp_data->cap[0]->NotRange.Reserved1 = 0x0031
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->NotButton.HasNull = 0
78pp_data->cap[0]->NotButton.Reserved4 = 0x000000
79pp_data->cap[0]->NotButton.LogicalMin = 0
80pp_data->cap[0]->NotButton.LogicalMax = -1
81pp_data->cap[0]->NotButton.PhysicalMin = 0
82pp_data->cap[0]->NotButton.PhysicalMax = -1
83pp_data->cap[0]->Units = 0
84pp_data->cap[0]->UnitsExp = 0
85
86pp_data->cap[1]->UsagePage = 0x0001
87pp_data->cap[1]->ReportID = 0x00
88pp_data->cap[1]->BitPosition = 0
89pp_data->cap[1]->BitSize = 16
90pp_data->cap[1]->ReportCount = 1
91pp_data->cap[1]->BytePosition = 0x0001
92pp_data->cap[1]->BitCount = 16
93pp_data->cap[1]->BitField = 0x02
94pp_data->cap[1]->NextBytePosition = 0x0003
95pp_data->cap[1]->LinkCollection = 0x0001
96pp_data->cap[1]->LinkUsagePage = 0x0001
97pp_data->cap[1]->LinkUsage = 0x0000
98pp_data->cap[1]->IsMultipleItemsForArray = 0
99pp_data->cap[1]->IsButtonCap = 0
100pp_data->cap[1]->IsPadding = 0
101pp_data->cap[1]->IsAbsolute = 1
102pp_data->cap[1]->IsRange = 0
103pp_data->cap[1]->IsAlias = 0
104pp_data->cap[1]->IsStringRange = 0
105pp_data->cap[1]->IsDesignatorRange = 0
106pp_data->cap[1]->Reserved1 = 0x000000
107pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
116pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
117pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
118pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
119pp_data->cap[1]->NotRange.Usage = 0x0030
120pp_data->cap[1]->NotRange.Reserved1 = 0x0030
121pp_data->cap[1]->NotRange.StringIndex = 0
122pp_data->cap[1]->NotRange.Reserved2 = 0
123pp_data->cap[1]->NotRange.DesignatorIndex = 0
124pp_data->cap[1]->NotRange.Reserved3 = 0
125pp_data->cap[1]->NotRange.DataIndex = 1
126pp_data->cap[1]->NotRange.Reserved4 = 1
127pp_data->cap[1]->NotButton.HasNull = 0
128pp_data->cap[1]->NotButton.Reserved4 = 0x000000
129pp_data->cap[1]->NotButton.LogicalMin = 0
130pp_data->cap[1]->NotButton.LogicalMax = -1
131pp_data->cap[1]->NotButton.PhysicalMin = 0
132pp_data->cap[1]->NotButton.PhysicalMax = -1
133pp_data->cap[1]->Units = 0
134pp_data->cap[1]->UnitsExp = 0
135
136pp_data->cap[2]->UsagePage = 0x0001
137pp_data->cap[2]->ReportID = 0x00
138pp_data->cap[2]->BitPosition = 0
139pp_data->cap[2]->BitSize = 16
140pp_data->cap[2]->ReportCount = 1
141pp_data->cap[2]->BytePosition = 0x0007
142pp_data->cap[2]->BitCount = 16
143pp_data->cap[2]->BitField = 0x02
144pp_data->cap[2]->NextBytePosition = 0x0009
145pp_data->cap[2]->LinkCollection = 0x0002
146pp_data->cap[2]->LinkUsagePage = 0x0001
147pp_data->cap[2]->LinkUsage = 0x0000
148pp_data->cap[2]->IsMultipleItemsForArray = 0
149pp_data->cap[2]->IsButtonCap = 0
150pp_data->cap[2]->IsPadding = 0
151pp_data->cap[2]->IsAbsolute = 1
152pp_data->cap[2]->IsRange = 0
153pp_data->cap[2]->IsAlias = 0
154pp_data->cap[2]->IsStringRange = 0
155pp_data->cap[2]->IsDesignatorRange = 0
156pp_data->cap[2]->Reserved1 = 0x000000
157pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
158pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
159pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
160pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
161pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
162pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
163pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
164pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
165pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
166pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
167pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
168pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
169pp_data->cap[2]->NotRange.Usage = 0x0034
170pp_data->cap[2]->NotRange.Reserved1 = 0x0034
171pp_data->cap[2]->NotRange.StringIndex = 0
172pp_data->cap[2]->NotRange.Reserved2 = 0
173pp_data->cap[2]->NotRange.DesignatorIndex = 0
174pp_data->cap[2]->NotRange.Reserved3 = 0
175pp_data->cap[2]->NotRange.DataIndex = 2
176pp_data->cap[2]->NotRange.Reserved4 = 2
177pp_data->cap[2]->NotButton.HasNull = 0
178pp_data->cap[2]->NotButton.Reserved4 = 0x000000
179pp_data->cap[2]->NotButton.LogicalMin = 0
180pp_data->cap[2]->NotButton.LogicalMax = -1
181pp_data->cap[2]->NotButton.PhysicalMin = 0
182pp_data->cap[2]->NotButton.PhysicalMax = -1
183pp_data->cap[2]->Units = 0
184pp_data->cap[2]->UnitsExp = 0
185
186pp_data->cap[3]->UsagePage = 0x0001
187pp_data->cap[3]->ReportID = 0x00
188pp_data->cap[3]->BitPosition = 0
189pp_data->cap[3]->BitSize = 16
190pp_data->cap[3]->ReportCount = 1
191pp_data->cap[3]->BytePosition = 0x0005
192pp_data->cap[3]->BitCount = 16
193pp_data->cap[3]->BitField = 0x02
194pp_data->cap[3]->NextBytePosition = 0x0007
195pp_data->cap[3]->LinkCollection = 0x0002
196pp_data->cap[3]->LinkUsagePage = 0x0001
197pp_data->cap[3]->LinkUsage = 0x0000
198pp_data->cap[3]->IsMultipleItemsForArray = 0
199pp_data->cap[3]->IsButtonCap = 0
200pp_data->cap[3]->IsPadding = 0
201pp_data->cap[3]->IsAbsolute = 1
202pp_data->cap[3]->IsRange = 0
203pp_data->cap[3]->IsAlias = 0
204pp_data->cap[3]->IsStringRange = 0
205pp_data->cap[3]->IsDesignatorRange = 0
206pp_data->cap[3]->Reserved1 = 0x000000
207pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
208pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
209pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
210pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
211pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
212pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
213pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
214pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
215pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
216pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
217pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
218pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
219pp_data->cap[3]->NotRange.Usage = 0x0033
220pp_data->cap[3]->NotRange.Reserved1 = 0x0033
221pp_data->cap[3]->NotRange.StringIndex = 0
222pp_data->cap[3]->NotRange.Reserved2 = 0
223pp_data->cap[3]->NotRange.DesignatorIndex = 0
224pp_data->cap[3]->NotRange.Reserved3 = 0
225pp_data->cap[3]->NotRange.DataIndex = 3
226pp_data->cap[3]->NotRange.Reserved4 = 3
227pp_data->cap[3]->NotButton.HasNull = 0
228pp_data->cap[3]->NotButton.Reserved4 = 0x000000
229pp_data->cap[3]->NotButton.LogicalMin = 0
230pp_data->cap[3]->NotButton.LogicalMax = -1
231pp_data->cap[3]->NotButton.PhysicalMin = 0
232pp_data->cap[3]->NotButton.PhysicalMax = -1
233pp_data->cap[3]->Units = 0
234pp_data->cap[3]->UnitsExp = 0
235
236pp_data->cap[4]->UsagePage = 0x0001
237pp_data->cap[4]->ReportID = 0x00
238pp_data->cap[4]->BitPosition = 0
239pp_data->cap[4]->BitSize = 16
240pp_data->cap[4]->ReportCount = 1
241pp_data->cap[4]->BytePosition = 0x0009
242pp_data->cap[4]->BitCount = 16
243pp_data->cap[4]->BitField = 0x02
244pp_data->cap[4]->NextBytePosition = 0x000B
245pp_data->cap[4]->LinkCollection = 0x0003
246pp_data->cap[4]->LinkUsagePage = 0x0001
247pp_data->cap[4]->LinkUsage = 0x0000
248pp_data->cap[4]->IsMultipleItemsForArray = 0
249pp_data->cap[4]->IsButtonCap = 0
250pp_data->cap[4]->IsPadding = 0
251pp_data->cap[4]->IsAbsolute = 1
252pp_data->cap[4]->IsRange = 0
253pp_data->cap[4]->IsAlias = 0
254pp_data->cap[4]->IsStringRange = 0
255pp_data->cap[4]->IsDesignatorRange = 0
256pp_data->cap[4]->Reserved1 = 0x000000
257pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
258pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
259pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
260pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
261pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
262pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
263pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
264pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
265pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
266pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
267pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
268pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
269pp_data->cap[4]->NotRange.Usage = 0x0032
270pp_data->cap[4]->NotRange.Reserved1 = 0x0032
271pp_data->cap[4]->NotRange.StringIndex = 0
272pp_data->cap[4]->NotRange.Reserved2 = 0
273pp_data->cap[4]->NotRange.DesignatorIndex = 0
274pp_data->cap[4]->NotRange.Reserved3 = 0
275pp_data->cap[4]->NotRange.DataIndex = 4
276pp_data->cap[4]->NotRange.Reserved4 = 4
277pp_data->cap[4]->NotButton.HasNull = 0
278pp_data->cap[4]->NotButton.Reserved4 = 0x000000
279pp_data->cap[4]->NotButton.LogicalMin = 0
280pp_data->cap[4]->NotButton.LogicalMax = -1
281pp_data->cap[4]->NotButton.PhysicalMin = 0
282pp_data->cap[4]->NotButton.PhysicalMax = -1
283pp_data->cap[4]->Units = 0
284pp_data->cap[4]->UnitsExp = 0
285
286pp_data->cap[5]->UsagePage = 0x0009
287pp_data->cap[5]->ReportID = 0x00
288pp_data->cap[5]->BitPosition = 0
289pp_data->cap[5]->BitSize = 1
290pp_data->cap[5]->ReportCount = 16
291pp_data->cap[5]->BytePosition = 0x000B
292pp_data->cap[5]->BitCount = 16
293pp_data->cap[5]->BitField = 0x02
294pp_data->cap[5]->NextBytePosition = 0x000D
295pp_data->cap[5]->LinkCollection = 0x0000
296pp_data->cap[5]->LinkUsagePage = 0x0001
297pp_data->cap[5]->LinkUsage = 0x0005
298pp_data->cap[5]->IsMultipleItemsForArray = 0
299pp_data->cap[5]->IsButtonCap = 1
300pp_data->cap[5]->IsPadding = 0
301pp_data->cap[5]->IsAbsolute = 1
302pp_data->cap[5]->IsRange = 1
303pp_data->cap[5]->IsAlias = 0
304pp_data->cap[5]->IsStringRange = 0
305pp_data->cap[5]->IsDesignatorRange = 0
306pp_data->cap[5]->Reserved1 = 0x000000
307pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
308pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
309pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
310pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
311pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
312pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
313pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
314pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
315pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
316pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
317pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
318pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
319pp_data->cap[5]->Range.UsageMin = 0x0001
320pp_data->cap[5]->Range.UsageMax = 0x0010
321pp_data->cap[5]->Range.StringMin = 0
322pp_data->cap[5]->Range.StringMax = 0
323pp_data->cap[5]->Range.DesignatorMin = 0
324pp_data->cap[5]->Range.DesignatorMax = 0
325pp_data->cap[5]->Range.DataIndexMin = 5
326pp_data->cap[5]->Range.DataIndexMax = 20
327pp_data->cap[5]->Button.LogicalMin = 0
328pp_data->cap[5]->Button.LogicalMax = 0
329pp_data->cap[5]->Units = 0
330pp_data->cap[5]->UnitsExp = 0
331
332pp_data->cap[6]->UsagePage = 0x0001
333pp_data->cap[6]->ReportID = 0x00
334pp_data->cap[6]->BitPosition = 0
335pp_data->cap[6]->BitSize = 4
336pp_data->cap[6]->ReportCount = 1
337pp_data->cap[6]->BytePosition = 0x000D
338pp_data->cap[6]->BitCount = 4
339pp_data->cap[6]->BitField = 0x42
340pp_data->cap[6]->NextBytePosition = 0x000E
341pp_data->cap[6]->LinkCollection = 0x0000
342pp_data->cap[6]->LinkUsagePage = 0x0001
343pp_data->cap[6]->LinkUsage = 0x0005
344pp_data->cap[6]->IsMultipleItemsForArray = 0
345pp_data->cap[6]->IsButtonCap = 0
346pp_data->cap[6]->IsPadding = 0
347pp_data->cap[6]->IsAbsolute = 1
348pp_data->cap[6]->IsRange = 0
349pp_data->cap[6]->IsAlias = 0
350pp_data->cap[6]->IsStringRange = 0
351pp_data->cap[6]->IsDesignatorRange = 0
352pp_data->cap[6]->Reserved1 = 0x000000
353pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
354pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
355pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
356pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
357pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
358pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
359pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
360pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
361pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
362pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
363pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
364pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
365pp_data->cap[6]->NotRange.Usage = 0x0039
366pp_data->cap[6]->NotRange.Reserved1 = 0x0039
367pp_data->cap[6]->NotRange.StringIndex = 0
368pp_data->cap[6]->NotRange.Reserved2 = 0
369pp_data->cap[6]->NotRange.DesignatorIndex = 0
370pp_data->cap[6]->NotRange.Reserved3 = 0
371pp_data->cap[6]->NotRange.DataIndex = 21
372pp_data->cap[6]->NotRange.Reserved4 = 21
373pp_data->cap[6]->NotButton.HasNull = 1
374pp_data->cap[6]->NotButton.Reserved4 = 0x000000
375pp_data->cap[6]->NotButton.LogicalMin = 1
376pp_data->cap[6]->NotButton.LogicalMax = 8
377pp_data->cap[6]->NotButton.PhysicalMin = 0
378pp_data->cap[6]->NotButton.PhysicalMax = 4155
379pp_data->cap[6]->Units = 14
380pp_data->cap[6]->UnitsExp = 0
381
382# Output hid_pp_cap struct:
383# Feature hid_pp_cap struct:
384# Link Collections:
385pp_data->LinkCollectionArray[0]->LinkUsage = 0x0005
386pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
387pp_data->LinkCollectionArray[0]->Parent = 0
388pp_data->LinkCollectionArray[0]->NumberOfChildren = 3
389pp_data->LinkCollectionArray[0]->NextSibling = 0
390pp_data->LinkCollectionArray[0]->FirstChild = 3
391pp_data->LinkCollectionArray[0]->CollectionType = 1
392pp_data->LinkCollectionArray[0]->IsAlias = 0
393pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
394pp_data->LinkCollectionArray[1]->LinkUsage = 0x0000
395pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
396pp_data->LinkCollectionArray[1]->Parent = 0
397pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
398pp_data->LinkCollectionArray[1]->NextSibling = 0
399pp_data->LinkCollectionArray[1]->FirstChild = 0
400pp_data->LinkCollectionArray[1]->CollectionType = 0
401pp_data->LinkCollectionArray[1]->IsAlias = 0
402pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
403pp_data->LinkCollectionArray[2]->LinkUsage = 0x0000
404pp_data->LinkCollectionArray[2]->LinkUsagePage = 0x0001
405pp_data->LinkCollectionArray[2]->Parent = 0
406pp_data->LinkCollectionArray[2]->NumberOfChildren = 0
407pp_data->LinkCollectionArray[2]->NextSibling = 1
408pp_data->LinkCollectionArray[2]->FirstChild = 0
409pp_data->LinkCollectionArray[2]->CollectionType = 0
410pp_data->LinkCollectionArray[2]->IsAlias = 0
411pp_data->LinkCollectionArray[2]->Reserved = 0x00000000
412pp_data->LinkCollectionArray[3]->LinkUsage = 0x0000
413pp_data->LinkCollectionArray[3]->LinkUsagePage = 0x0001
414pp_data->LinkCollectionArray[3]->Parent = 0
415pp_data->LinkCollectionArray[3]->NumberOfChildren = 0
416pp_data->LinkCollectionArray[3]->NextSibling = 2
417pp_data->LinkCollectionArray[3]->FirstChild = 0
418pp_data->LinkCollectionArray[3]->CollectionType = 0
419pp_data->LinkCollectionArray[3]->IsAlias = 0
420pp_data->LinkCollectionArray[3]->Reserved = 0x00000000 \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_expected.rpt_desc
new file mode 100644
index 0000000..58f80e4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_expected.rpt_desc
@@ -0,0 +1,12 @@
10x05, 0x01, 0x09, 0x05, 0xA1, 0x01, 0x09, 0x00, 0xA1, 0x00,
20x09, 0x30, 0x09, 0x31, 0x15, 0x00, 0x25, 0xFF, 0x35, 0x00,
30x45, 0xFF, 0x75, 0x10, 0x95, 0x02, 0x81, 0x02, 0xC0, 0x09,
40x00, 0xA1, 0x00, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x25,
50xFF, 0x75, 0x10, 0x95, 0x02, 0x81, 0x02, 0xC0, 0x09, 0x00,
60xA1, 0x00, 0x09, 0x32, 0x15, 0x00, 0x25, 0xFF, 0x75, 0x10,
70x95, 0x01, 0x81, 0x02, 0xC0, 0x05, 0x09, 0x19, 0x01, 0x29,
80x10, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x10, 0x45,
90x00, 0x81, 0x02, 0x05, 0x01, 0x09, 0x39, 0x15, 0x01, 0x25,
100x08, 0x35, 0x00, 0x46, 0x3B, 0x10, 0x65, 0x0E, 0x75, 0x04,
110x95, 0x01, 0x81, 0x42, 0x75, 0x04, 0x95, 0x01, 0x81, 0x03,
120xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_real.rpt_desc
new file mode 100644
index 0000000..11cc78b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/045E_02FF_0005_0001_real.rpt_desc
@@ -0,0 +1,64 @@
1// Special cases of this device:
2// 2 full padding bytes at the end
3// Multiple child collections inside of the same report (byte position of Input items defines collection order)
4
50x05, 0x01, // Usage Page (Generic Desktop Ctrls)
60x09, 0x05, // Usage (Game Pad)
70xA1, 0x01, // Collection (Application)
80xA1, 0x00, // Collection (Physical)
90x09, 0x30, // Usage (X)
100x09, 0x31, // Usage (Y)
110x15, 0x00, // Logical Minimum (0)
120x26, 0xFF, 0xFF, // Logical Maximum (-1)
130x35, 0x00, // Physical Minimum (0)
140x46, 0xFF, 0xFF, // Physical Maximum (-1)
150x95, 0x02, // Report Count (2)
160x75, 0x10, // Report Size (16)
170x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
180xC0, // End Collection
190xA1, 0x00, // Collection (Physical)
200x09, 0x33, // Usage (Rx)
210x09, 0x34, // Usage (Ry)
220x15, 0x00, // Logical Minimum (0)
230x26, 0xFF, 0xFF, // Logical Maximum (-1)
240x35, 0x00, // Physical Minimum (0)
250x46, 0xFF, 0xFF, // Physical Maximum (-1)
260x95, 0x02, // Report Count (2)
270x75, 0x10, // Report Size (16)
280x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
290xC0, // End Collection
300xA1, 0x00, // Collection (Physical)
310x09, 0x32, // Usage (Z)
320x15, 0x00, // Logical Minimum (0)
330x26, 0xFF, 0xFF, // Logical Maximum (-1)
340x35, 0x00, // Physical Minimum (0)
350x46, 0xFF, 0xFF, // Physical Maximum (-1)
360x95, 0x01, // Report Count (1)
370x75, 0x10, // Report Size (16)
380x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
390xC0, // End Collection
400x05, 0x09, // Usage Page (Button)
410x19, 0x01, // Usage Minimum (0x01)
420x29, 0x10, // Usage Maximum (0x10)
430x95, 0x10, // Report Count (16)
440x75, 0x01, // Report Size (1)
450x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
460x05, 0x01, // Usage Page (Generic Desktop Ctrls)
470x09, 0x39, // Usage (Hat switch)
480x15, 0x01, // Logical Minimum (1)
490x25, 0x08, // Logical Maximum (8)
500x35, 0x00, // Physical Minimum (0)
510x46, 0x3B, 0x10, // Physical Maximum (4155)
520x66, 0x0E, 0x00, // Unit (None)
530x75, 0x04, // Report Size (4)
540x95, 0x01, // Report Count (1)
550x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
560x75, 0x04, // Report Size (4)
570x95, 0x01, // Report Count (1)
580x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
590x75, 0x08, // Report Size (8)
600x95, 0x02, // Report Count (2)
610x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
620xC0, // End Collection
63
64// 120 bytes \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001.pp_data
new file mode 100644
index 0000000..59eb600
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001.pp_data
@@ -0,0 +1,183 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046A
3dev->product_id = 0x0011
4dev->manufacturer_string = "dev->product_string = "dev->release_number = 0x0100
5dev->interface_number = -1
6dev->usage = 0x0006
7dev->usage_page = 0x0001
8dev->path = "\\?\hid#vid_046a&pid_0011#7&2c7fd0a5&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
9
10# Preparsed Data struct:
11pp_data->MagicKey = 0x48696450204B4452
12pp_data->Usage = 0x0006
13pp_data->UsagePage = 0x0001
14pp_data->Reserved = 0x00000000
15# Input caps_info struct:
16pp_data->caps_info[0]->FirstCap = 0
17pp_data->caps_info[0]->LastCap = 2
18pp_data->caps_info[0]->NumberOfCaps = 2
19pp_data->caps_info[0]->ReportByteLength = 9
20# Output caps_info struct:
21pp_data->caps_info[1]->FirstCap = 2
22pp_data->caps_info[1]->LastCap = 3
23pp_data->caps_info[1]->NumberOfCaps = 1
24pp_data->caps_info[1]->ReportByteLength = 2
25# Feature caps_info struct:
26pp_data->caps_info[2]->FirstCap = 3
27pp_data->caps_info[2]->LastCap = 3
28pp_data->caps_info[2]->NumberOfCaps = 0
29pp_data->caps_info[2]->ReportByteLength = 0
30# LinkCollectionArray Offset & Size:
31pp_data->FirstByteOfLinkCollectionArray = 0x0138
32pp_data->NumberLinkCollectionNodes = 1
33# Input hid_pp_cap struct:
34pp_data->cap[0]->UsagePage = 0x0007
35pp_data->cap[0]->ReportID = 0x00
36pp_data->cap[0]->BitPosition = 0
37pp_data->cap[0]->BitSize = 1
38pp_data->cap[0]->ReportCount = 8
39pp_data->cap[0]->BytePosition = 0x0001
40pp_data->cap[0]->BitCount = 8
41pp_data->cap[0]->BitField = 0x02
42pp_data->cap[0]->NextBytePosition = 0x0002
43pp_data->cap[0]->LinkCollection = 0x0000
44pp_data->cap[0]->LinkUsagePage = 0x0001
45pp_data->cap[0]->LinkUsage = 0x0006
46pp_data->cap[0]->IsMultipleItemsForArray = 0
47pp_data->cap[0]->IsButtonCap = 1
48pp_data->cap[0]->IsPadding = 0
49pp_data->cap[0]->IsAbsolute = 1
50pp_data->cap[0]->IsRange = 1
51pp_data->cap[0]->IsAlias = 0
52pp_data->cap[0]->IsStringRange = 0
53pp_data->cap[0]->IsDesignatorRange = 0
54pp_data->cap[0]->Reserved1 = 0x000000
55pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
56pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
58pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
59pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
61pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
62pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
64pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
65pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
67pp_data->cap[0]->Range.UsageMin = 0x00E0
68pp_data->cap[0]->Range.UsageMax = 0x00E7
69pp_data->cap[0]->Range.StringMin = 0
70pp_data->cap[0]->Range.StringMax = 0
71pp_data->cap[0]->Range.DesignatorMin = 0
72pp_data->cap[0]->Range.DesignatorMax = 0
73pp_data->cap[0]->Range.DataIndexMin = 0
74pp_data->cap[0]->Range.DataIndexMax = 7
75pp_data->cap[0]->Button.LogicalMin = 0
76pp_data->cap[0]->Button.LogicalMax = 0
77pp_data->cap[0]->Units = 0
78pp_data->cap[0]->UnitsExp = 0
79
80pp_data->cap[1]->UsagePage = 0x0007
81pp_data->cap[1]->ReportID = 0x00
82pp_data->cap[1]->BitPosition = 0
83pp_data->cap[1]->BitSize = 8
84pp_data->cap[1]->ReportCount = 6
85pp_data->cap[1]->BytePosition = 0x0003
86pp_data->cap[1]->BitCount = 48
87pp_data->cap[1]->BitField = 0x00
88pp_data->cap[1]->NextBytePosition = 0x0009
89pp_data->cap[1]->LinkCollection = 0x0000
90pp_data->cap[1]->LinkUsagePage = 0x0001
91pp_data->cap[1]->LinkUsage = 0x0006
92pp_data->cap[1]->IsMultipleItemsForArray = 0
93pp_data->cap[1]->IsButtonCap = 1
94pp_data->cap[1]->IsPadding = 0
95pp_data->cap[1]->IsAbsolute = 1
96pp_data->cap[1]->IsRange = 1
97pp_data->cap[1]->IsAlias = 0
98pp_data->cap[1]->IsStringRange = 0
99pp_data->cap[1]->IsDesignatorRange = 0
100pp_data->cap[1]->Reserved1 = 0x000000
101pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
102pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
104pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
105pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
107pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
113pp_data->cap[1]->Range.UsageMin = 0x0000
114pp_data->cap[1]->Range.UsageMax = 0x00DD
115pp_data->cap[1]->Range.StringMin = 0
116pp_data->cap[1]->Range.StringMax = 0
117pp_data->cap[1]->Range.DesignatorMin = 0
118pp_data->cap[1]->Range.DesignatorMax = 0
119pp_data->cap[1]->Range.DataIndexMin = 8
120pp_data->cap[1]->Range.DataIndexMax = 229
121pp_data->cap[1]->Button.LogicalMin = 0
122pp_data->cap[1]->Button.LogicalMax = 221
123pp_data->cap[1]->Units = 0
124pp_data->cap[1]->UnitsExp = 0
125
126# Output hid_pp_cap struct:
127pp_data->cap[2]->UsagePage = 0x0008
128pp_data->cap[2]->ReportID = 0x00
129pp_data->cap[2]->BitPosition = 0
130pp_data->cap[2]->BitSize = 1
131pp_data->cap[2]->ReportCount = 3
132pp_data->cap[2]->BytePosition = 0x0001
133pp_data->cap[2]->BitCount = 3
134pp_data->cap[2]->BitField = 0x02
135pp_data->cap[2]->NextBytePosition = 0x0002
136pp_data->cap[2]->LinkCollection = 0x0000
137pp_data->cap[2]->LinkUsagePage = 0x0001
138pp_data->cap[2]->LinkUsage = 0x0006
139pp_data->cap[2]->IsMultipleItemsForArray = 0
140pp_data->cap[2]->IsButtonCap = 1
141pp_data->cap[2]->IsPadding = 0
142pp_data->cap[2]->IsAbsolute = 1
143pp_data->cap[2]->IsRange = 1
144pp_data->cap[2]->IsAlias = 0
145pp_data->cap[2]->IsStringRange = 0
146pp_data->cap[2]->IsDesignatorRange = 0
147pp_data->cap[2]->Reserved1 = 0x000000
148pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
149pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
150pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
151pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
152pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
153pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
154pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
155pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
156pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
157pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
158pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
159pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
160pp_data->cap[2]->Range.UsageMin = 0x0001
161pp_data->cap[2]->Range.UsageMax = 0x0003
162pp_data->cap[2]->Range.StringMin = 0
163pp_data->cap[2]->Range.StringMax = 0
164pp_data->cap[2]->Range.DesignatorMin = 0
165pp_data->cap[2]->Range.DesignatorMax = 0
166pp_data->cap[2]->Range.DataIndexMin = 0
167pp_data->cap[2]->Range.DataIndexMax = 2
168pp_data->cap[2]->Button.LogicalMin = 0
169pp_data->cap[2]->Button.LogicalMax = 0
170pp_data->cap[2]->Units = 0
171pp_data->cap[2]->UnitsExp = 0
172
173# Feature hid_pp_cap struct:
174# Link Collections:
175pp_data->LinkCollectionArray[0]->LinkUsage = 0x0006
176pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
177pp_data->LinkCollectionArray[0]->Parent = 0
178pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
179pp_data->LinkCollectionArray[0]->NextSibling = 0
180pp_data->LinkCollectionArray[0]->FirstChild = 0
181pp_data->LinkCollectionArray[0]->CollectionType = 1
182pp_data->LinkCollectionArray[0]->IsAlias = 0
183pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_expected.rpt_desc
new file mode 100644
index 0000000..e9bc501
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_expected.rpt_desc
@@ -0,0 +1,7 @@
10x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0,
20x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
30x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03, 0x19, 0x00,
40x29, 0xDD, 0x15, 0x00, 0x26, 0xDD, 0x00, 0x75, 0x08, 0x95,
50x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x15,
60x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x03, 0x91, 0x02, 0x75,
70x05, 0x95, 0x01, 0x91, 0x03, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_real.rpt_desc
new file mode 100644
index 0000000..e9bc501
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046A_0011_0006_0001_real.rpt_desc
@@ -0,0 +1,7 @@
10x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0,
20x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
30x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03, 0x19, 0x00,
40x29, 0xDD, 0x15, 0x00, 0x26, 0xDD, 0x00, 0x75, 0x08, 0x95,
50x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x15,
60x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x03, 0x91, 0x02, 0x75,
70x05, 0x95, 0x01, 0x91, 0x03, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C.pp_data
new file mode 100644
index 0000000..3bc7aad
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C.pp_data
@@ -0,0 +1,532 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0x0A37
4dev->manufacturer_string = "Logitech Inc "
5dev->product_string = "Logitech USB Headset H540"
6dev->release_number = 0x0122
7dev->interface_number = 3
8dev->usage = 0x0001
9dev->usage_page = 0x000C
10dev->path = "\\?\hid#vid_046d&pid_0a37&mi_03#8&1717f300&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0x000C
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 7
20pp_data->caps_info[0]->NumberOfCaps = 9
21pp_data->caps_info[0]->ReportByteLength = 33
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 9
24pp_data->caps_info[1]->LastCap = 12
25pp_data->caps_info[1]->NumberOfCaps = 3
26pp_data->caps_info[1]->ReportByteLength = 37
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 12
29pp_data->caps_info[2]->LastCap = 12
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x04E0
34pp_data->NumberLinkCollectionNodes = 2
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x000C
37pp_data->cap[0]->ReportID = 0x01
38pp_data->cap[0]->BitPosition = 1
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 1
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x000C
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x00EA
70pp_data->cap[0]->NotRange.Reserved1 = 0x00EA
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x000C
83pp_data->cap[1]->ReportID = 0x01
84pp_data->cap[1]->BitPosition = 0
85pp_data->cap[1]->BitSize = 1
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0001
88pp_data->cap[1]->BitCount = 1
89pp_data->cap[1]->BitField = 0x02
90pp_data->cap[1]->NextBytePosition = 0x0002
91pp_data->cap[1]->LinkCollection = 0x0000
92pp_data->cap[1]->LinkUsagePage = 0x000C
93pp_data->cap[1]->LinkUsage = 0x0001
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 1
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 1
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x00E9
116pp_data->cap[1]->NotRange.Reserved1 = 0x00E9
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 1
122pp_data->cap[1]->NotRange.Reserved4 = 1
123pp_data->cap[1]->Button.LogicalMin = 0
124pp_data->cap[1]->Button.LogicalMax = 0
125pp_data->cap[1]->Units = 0
126pp_data->cap[1]->UnitsExp = 0
127
128pp_data->cap[2]->UsagePage = 0x000C
129pp_data->cap[2]->ReportID = 0x01
130pp_data->cap[2]->BitPosition = 2
131pp_data->cap[2]->BitSize = 1
132pp_data->cap[2]->ReportCount = 1
133pp_data->cap[2]->BytePosition = 0x0001
134pp_data->cap[2]->BitCount = 1
135pp_data->cap[2]->BitField = 0x06
136pp_data->cap[2]->NextBytePosition = 0x0002
137pp_data->cap[2]->LinkCollection = 0x0000
138pp_data->cap[2]->LinkUsagePage = 0x000C
139pp_data->cap[2]->LinkUsage = 0x0001
140pp_data->cap[2]->IsMultipleItemsForArray = 0
141pp_data->cap[2]->IsButtonCap = 1
142pp_data->cap[2]->IsPadding = 0
143pp_data->cap[2]->IsAbsolute = 0
144pp_data->cap[2]->IsRange = 0
145pp_data->cap[2]->IsAlias = 0
146pp_data->cap[2]->IsStringRange = 0
147pp_data->cap[2]->IsDesignatorRange = 0
148pp_data->cap[2]->Reserved1 = 0x000000
149pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
150pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
151pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
152pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
153pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
154pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
155pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
156pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
157pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
158pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
159pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
160pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
161pp_data->cap[2]->NotRange.Usage = 0x00E2
162pp_data->cap[2]->NotRange.Reserved1 = 0x00E2
163pp_data->cap[2]->NotRange.StringIndex = 0
164pp_data->cap[2]->NotRange.Reserved2 = 0
165pp_data->cap[2]->NotRange.DesignatorIndex = 0
166pp_data->cap[2]->NotRange.Reserved3 = 0
167pp_data->cap[2]->NotRange.DataIndex = 2
168pp_data->cap[2]->NotRange.Reserved4 = 2
169pp_data->cap[2]->Button.LogicalMin = 0
170pp_data->cap[2]->Button.LogicalMax = 0
171pp_data->cap[2]->Units = 0
172pp_data->cap[2]->UnitsExp = 0
173
174pp_data->cap[3]->UsagePage = 0x0009
175pp_data->cap[3]->ReportID = 0x01
176pp_data->cap[3]->BitPosition = 5
177pp_data->cap[3]->BitSize = 2
178pp_data->cap[3]->ReportCount = 1
179pp_data->cap[3]->BytePosition = 0x0001
180pp_data->cap[3]->BitCount = 2
181pp_data->cap[3]->BitField = 0x40
182pp_data->cap[3]->NextBytePosition = 0x0002
183pp_data->cap[3]->LinkCollection = 0x0001
184pp_data->cap[3]->LinkUsagePage = 0x000C
185pp_data->cap[3]->LinkUsage = 0x0036
186pp_data->cap[3]->IsMultipleItemsForArray = 0
187pp_data->cap[3]->IsButtonCap = 1
188pp_data->cap[3]->IsPadding = 0
189pp_data->cap[3]->IsAbsolute = 1
190pp_data->cap[3]->IsRange = 1
191pp_data->cap[3]->IsAlias = 0
192pp_data->cap[3]->IsStringRange = 0
193pp_data->cap[3]->IsDesignatorRange = 0
194pp_data->cap[3]->Reserved1 = 0x000000
195pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
196pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
197pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
198pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
199pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
200pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
201pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
202pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
203pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
204pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
205pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
206pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
207pp_data->cap[3]->Range.UsageMin = 0x0001
208pp_data->cap[3]->Range.UsageMax = 0x0002
209pp_data->cap[3]->Range.StringMin = 0
210pp_data->cap[3]->Range.StringMax = 0
211pp_data->cap[3]->Range.DesignatorMin = 0
212pp_data->cap[3]->Range.DesignatorMax = 0
213pp_data->cap[3]->Range.DataIndexMin = 3
214pp_data->cap[3]->Range.DataIndexMax = 4
215pp_data->cap[3]->Button.LogicalMin = 1
216pp_data->cap[3]->Button.LogicalMax = 2
217pp_data->cap[3]->Units = 0
218pp_data->cap[3]->UnitsExp = 0
219
220pp_data->cap[4]->UsagePage = 0x000C
221pp_data->cap[4]->ReportID = 0x02
222pp_data->cap[4]->BitPosition = 0
223pp_data->cap[4]->BitSize = 1
224pp_data->cap[4]->ReportCount = 16
225pp_data->cap[4]->BytePosition = 0x0001
226pp_data->cap[4]->BitCount = 16
227pp_data->cap[4]->BitField = 0x02
228pp_data->cap[4]->NextBytePosition = 0x0003
229pp_data->cap[4]->LinkCollection = 0x0000
230pp_data->cap[4]->LinkUsagePage = 0x000C
231pp_data->cap[4]->LinkUsage = 0x0001
232pp_data->cap[4]->IsMultipleItemsForArray = 0
233pp_data->cap[4]->IsButtonCap = 1
234pp_data->cap[4]->IsPadding = 0
235pp_data->cap[4]->IsAbsolute = 1
236pp_data->cap[4]->IsRange = 0
237pp_data->cap[4]->IsAlias = 0
238pp_data->cap[4]->IsStringRange = 0
239pp_data->cap[4]->IsDesignatorRange = 0
240pp_data->cap[4]->Reserved1 = 0x000000
241pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
242pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
243pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
244pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
245pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
246pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
247pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
248pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
249pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
250pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
251pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
252pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
253pp_data->cap[4]->NotRange.Usage = 0x0000
254pp_data->cap[4]->NotRange.Reserved1 = 0x0000
255pp_data->cap[4]->NotRange.StringIndex = 0
256pp_data->cap[4]->NotRange.Reserved2 = 0
257pp_data->cap[4]->NotRange.DesignatorIndex = 0
258pp_data->cap[4]->NotRange.Reserved3 = 0
259pp_data->cap[4]->NotRange.DataIndex = 5
260pp_data->cap[4]->NotRange.Reserved4 = 5
261pp_data->cap[4]->Button.LogicalMin = 0
262pp_data->cap[4]->Button.LogicalMax = 0
263pp_data->cap[4]->Units = 0
264pp_data->cap[4]->UnitsExp = 0
265
266pp_data->cap[5]->UsagePage = 0x000C
267pp_data->cap[5]->ReportID = 0x05
268pp_data->cap[5]->BitPosition = 0
269pp_data->cap[5]->BitSize = 8
270pp_data->cap[5]->ReportCount = 32
271pp_data->cap[5]->BytePosition = 0x0001
272pp_data->cap[5]->BitCount = 256
273pp_data->cap[5]->BitField = 0x02
274pp_data->cap[5]->NextBytePosition = 0x0021
275pp_data->cap[5]->LinkCollection = 0x0000
276pp_data->cap[5]->LinkUsagePage = 0x000C
277pp_data->cap[5]->LinkUsage = 0x0001
278pp_data->cap[5]->IsMultipleItemsForArray = 0
279pp_data->cap[5]->IsButtonCap = 0
280pp_data->cap[5]->IsPadding = 0
281pp_data->cap[5]->IsAbsolute = 1
282pp_data->cap[5]->IsRange = 0
283pp_data->cap[5]->IsAlias = 0
284pp_data->cap[5]->IsStringRange = 0
285pp_data->cap[5]->IsDesignatorRange = 0
286pp_data->cap[5]->Reserved1 = 0x000000
287pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
288pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
289pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
290pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
291pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
292pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
293pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
294pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
295pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
296pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
297pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
298pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
299pp_data->cap[5]->NotRange.Usage = 0x0000
300pp_data->cap[5]->NotRange.Reserved1 = 0x0000
301pp_data->cap[5]->NotRange.StringIndex = 0
302pp_data->cap[5]->NotRange.Reserved2 = 0
303pp_data->cap[5]->NotRange.DesignatorIndex = 0
304pp_data->cap[5]->NotRange.Reserved3 = 0
305pp_data->cap[5]->NotRange.DataIndex = 6
306pp_data->cap[5]->NotRange.Reserved4 = 6
307pp_data->cap[5]->NotButton.HasNull = 0
308pp_data->cap[5]->NotButton.Reserved4 = 0x000000
309pp_data->cap[5]->NotButton.LogicalMin = 0
310pp_data->cap[5]->NotButton.LogicalMax = 1
311pp_data->cap[5]->NotButton.PhysicalMin = 0
312pp_data->cap[5]->NotButton.PhysicalMax = 0
313pp_data->cap[5]->Units = 0
314pp_data->cap[5]->UnitsExp = 0
315
316pp_data->cap[6]->UsagePage = 0x000C
317pp_data->cap[6]->ReportID = 0x07
318pp_data->cap[6]->BitPosition = 0
319pp_data->cap[6]->BitSize = 8
320pp_data->cap[6]->ReportCount = 32
321pp_data->cap[6]->BytePosition = 0x0001
322pp_data->cap[6]->BitCount = 256
323pp_data->cap[6]->BitField = 0x02
324pp_data->cap[6]->NextBytePosition = 0x0021
325pp_data->cap[6]->LinkCollection = 0x0000
326pp_data->cap[6]->LinkUsagePage = 0x000C
327pp_data->cap[6]->LinkUsage = 0x0001
328pp_data->cap[6]->IsMultipleItemsForArray = 0
329pp_data->cap[6]->IsButtonCap = 0
330pp_data->cap[6]->IsPadding = 0
331pp_data->cap[6]->IsAbsolute = 1
332pp_data->cap[6]->IsRange = 0
333pp_data->cap[6]->IsAlias = 0
334pp_data->cap[6]->IsStringRange = 0
335pp_data->cap[6]->IsDesignatorRange = 0
336pp_data->cap[6]->Reserved1 = 0x000000
337pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
338pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
339pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
340pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
341pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
342pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
343pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
344pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
345pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
346pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
347pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
348pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
349pp_data->cap[6]->NotRange.Usage = 0x0000
350pp_data->cap[6]->NotRange.Reserved1 = 0x0000
351pp_data->cap[6]->NotRange.StringIndex = 0
352pp_data->cap[6]->NotRange.Reserved2 = 0
353pp_data->cap[6]->NotRange.DesignatorIndex = 0
354pp_data->cap[6]->NotRange.Reserved3 = 0
355pp_data->cap[6]->NotRange.DataIndex = 7
356pp_data->cap[6]->NotRange.Reserved4 = 7
357pp_data->cap[6]->NotButton.HasNull = 0
358pp_data->cap[6]->NotButton.Reserved4 = 0x000000
359pp_data->cap[6]->NotButton.LogicalMin = 0
360pp_data->cap[6]->NotButton.LogicalMax = 1
361pp_data->cap[6]->NotButton.PhysicalMin = 0
362pp_data->cap[6]->NotButton.PhysicalMax = 0
363pp_data->cap[6]->Units = 0
364pp_data->cap[6]->UnitsExp = 0
365
366# Output hid_pp_cap struct:
367pp_data->cap[9]->UsagePage = 0x000C
368pp_data->cap[9]->ReportID = 0x03
369pp_data->cap[9]->BitPosition = 0
370pp_data->cap[9]->BitSize = 1
371pp_data->cap[9]->ReportCount = 16
372pp_data->cap[9]->BytePosition = 0x0001
373pp_data->cap[9]->BitCount = 16
374pp_data->cap[9]->BitField = 0x02
375pp_data->cap[9]->NextBytePosition = 0x0003
376pp_data->cap[9]->LinkCollection = 0x0000
377pp_data->cap[9]->LinkUsagePage = 0x000C
378pp_data->cap[9]->LinkUsage = 0x0001
379pp_data->cap[9]->IsMultipleItemsForArray = 0
380pp_data->cap[9]->IsButtonCap = 1
381pp_data->cap[9]->IsPadding = 0
382pp_data->cap[9]->IsAbsolute = 1
383pp_data->cap[9]->IsRange = 0
384pp_data->cap[9]->IsAlias = 0
385pp_data->cap[9]->IsStringRange = 0
386pp_data->cap[9]->IsDesignatorRange = 0
387pp_data->cap[9]->Reserved1 = 0x000000
388pp_data->cap[9]->pp_cap->UnknownTokens[0].Token = 0x00
389pp_data->cap[9]->pp_cap->UnknownTokens[0].Reserved = 0x000000
390pp_data->cap[9]->pp_cap->UnknownTokens[0].BitField = 0x00000000
391pp_data->cap[9]->pp_cap->UnknownTokens[1].Token = 0x00
392pp_data->cap[9]->pp_cap->UnknownTokens[1].Reserved = 0x000000
393pp_data->cap[9]->pp_cap->UnknownTokens[1].BitField = 0x00000000
394pp_data->cap[9]->pp_cap->UnknownTokens[2].Token = 0x00
395pp_data->cap[9]->pp_cap->UnknownTokens[2].Reserved = 0x000000
396pp_data->cap[9]->pp_cap->UnknownTokens[2].BitField = 0x00000000
397pp_data->cap[9]->pp_cap->UnknownTokens[3].Token = 0x00
398pp_data->cap[9]->pp_cap->UnknownTokens[3].Reserved = 0x000000
399pp_data->cap[9]->pp_cap->UnknownTokens[3].BitField = 0x00000000
400pp_data->cap[9]->NotRange.Usage = 0x0000
401pp_data->cap[9]->NotRange.Reserved1 = 0x0000
402pp_data->cap[9]->NotRange.StringIndex = 0
403pp_data->cap[9]->NotRange.Reserved2 = 0
404pp_data->cap[9]->NotRange.DesignatorIndex = 0
405pp_data->cap[9]->NotRange.Reserved3 = 0
406pp_data->cap[9]->NotRange.DataIndex = 0
407pp_data->cap[9]->NotRange.Reserved4 = 0
408pp_data->cap[9]->Button.LogicalMin = 0
409pp_data->cap[9]->Button.LogicalMax = 0
410pp_data->cap[9]->Units = 0
411pp_data->cap[9]->UnitsExp = 0
412
413pp_data->cap[10]->UsagePage = 0x000C
414pp_data->cap[10]->ReportID = 0x04
415pp_data->cap[10]->BitPosition = 0
416pp_data->cap[10]->BitSize = 8
417pp_data->cap[10]->ReportCount = 36
418pp_data->cap[10]->BytePosition = 0x0001
419pp_data->cap[10]->BitCount = 288
420pp_data->cap[10]->BitField = 0x02
421pp_data->cap[10]->NextBytePosition = 0x0025
422pp_data->cap[10]->LinkCollection = 0x0000
423pp_data->cap[10]->LinkUsagePage = 0x000C
424pp_data->cap[10]->LinkUsage = 0x0001
425pp_data->cap[10]->IsMultipleItemsForArray = 0
426pp_data->cap[10]->IsButtonCap = 0
427pp_data->cap[10]->IsPadding = 0
428pp_data->cap[10]->IsAbsolute = 1
429pp_data->cap[10]->IsRange = 0
430pp_data->cap[10]->IsAlias = 0
431pp_data->cap[10]->IsStringRange = 0
432pp_data->cap[10]->IsDesignatorRange = 0
433pp_data->cap[10]->Reserved1 = 0x000000
434pp_data->cap[10]->pp_cap->UnknownTokens[0].Token = 0x00
435pp_data->cap[10]->pp_cap->UnknownTokens[0].Reserved = 0x000000
436pp_data->cap[10]->pp_cap->UnknownTokens[0].BitField = 0x00000000
437pp_data->cap[10]->pp_cap->UnknownTokens[1].Token = 0x00
438pp_data->cap[10]->pp_cap->UnknownTokens[1].Reserved = 0x000000
439pp_data->cap[10]->pp_cap->UnknownTokens[1].BitField = 0x00000000
440pp_data->cap[10]->pp_cap->UnknownTokens[2].Token = 0x00
441pp_data->cap[10]->pp_cap->UnknownTokens[2].Reserved = 0x000000
442pp_data->cap[10]->pp_cap->UnknownTokens[2].BitField = 0x00000000
443pp_data->cap[10]->pp_cap->UnknownTokens[3].Token = 0x00
444pp_data->cap[10]->pp_cap->UnknownTokens[3].Reserved = 0x000000
445pp_data->cap[10]->pp_cap->UnknownTokens[3].BitField = 0x00000000
446pp_data->cap[10]->NotRange.Usage = 0x0000
447pp_data->cap[10]->NotRange.Reserved1 = 0x0000
448pp_data->cap[10]->NotRange.StringIndex = 0
449pp_data->cap[10]->NotRange.Reserved2 = 0
450pp_data->cap[10]->NotRange.DesignatorIndex = 0
451pp_data->cap[10]->NotRange.Reserved3 = 0
452pp_data->cap[10]->NotRange.DataIndex = 1
453pp_data->cap[10]->NotRange.Reserved4 = 1
454pp_data->cap[10]->NotButton.HasNull = 0
455pp_data->cap[10]->NotButton.Reserved4 = 0x000000
456pp_data->cap[10]->NotButton.LogicalMin = 0
457pp_data->cap[10]->NotButton.LogicalMax = 1
458pp_data->cap[10]->NotButton.PhysicalMin = 0
459pp_data->cap[10]->NotButton.PhysicalMax = 0
460pp_data->cap[10]->Units = 0
461pp_data->cap[10]->UnitsExp = 0
462
463pp_data->cap[11]->UsagePage = 0x000C
464pp_data->cap[11]->ReportID = 0x06
465pp_data->cap[11]->BitPosition = 0
466pp_data->cap[11]->BitSize = 8
467pp_data->cap[11]->ReportCount = 36
468pp_data->cap[11]->BytePosition = 0x0001
469pp_data->cap[11]->BitCount = 288
470pp_data->cap[11]->BitField = 0x02
471pp_data->cap[11]->NextBytePosition = 0x0025
472pp_data->cap[11]->LinkCollection = 0x0000
473pp_data->cap[11]->LinkUsagePage = 0x000C
474pp_data->cap[11]->LinkUsage = 0x0001
475pp_data->cap[11]->IsMultipleItemsForArray = 0
476pp_data->cap[11]->IsButtonCap = 0
477pp_data->cap[11]->IsPadding = 0
478pp_data->cap[11]->IsAbsolute = 1
479pp_data->cap[11]->IsRange = 0
480pp_data->cap[11]->IsAlias = 0
481pp_data->cap[11]->IsStringRange = 0
482pp_data->cap[11]->IsDesignatorRange = 0
483pp_data->cap[11]->Reserved1 = 0x000000
484pp_data->cap[11]->pp_cap->UnknownTokens[0].Token = 0x00
485pp_data->cap[11]->pp_cap->UnknownTokens[0].Reserved = 0x000000
486pp_data->cap[11]->pp_cap->UnknownTokens[0].BitField = 0x00000000
487pp_data->cap[11]->pp_cap->UnknownTokens[1].Token = 0x00
488pp_data->cap[11]->pp_cap->UnknownTokens[1].Reserved = 0x000000
489pp_data->cap[11]->pp_cap->UnknownTokens[1].BitField = 0x00000000
490pp_data->cap[11]->pp_cap->UnknownTokens[2].Token = 0x00
491pp_data->cap[11]->pp_cap->UnknownTokens[2].Reserved = 0x000000
492pp_data->cap[11]->pp_cap->UnknownTokens[2].BitField = 0x00000000
493pp_data->cap[11]->pp_cap->UnknownTokens[3].Token = 0x00
494pp_data->cap[11]->pp_cap->UnknownTokens[3].Reserved = 0x000000
495pp_data->cap[11]->pp_cap->UnknownTokens[3].BitField = 0x00000000
496pp_data->cap[11]->NotRange.Usage = 0x0000
497pp_data->cap[11]->NotRange.Reserved1 = 0x0000
498pp_data->cap[11]->NotRange.StringIndex = 0
499pp_data->cap[11]->NotRange.Reserved2 = 0
500pp_data->cap[11]->NotRange.DesignatorIndex = 0
501pp_data->cap[11]->NotRange.Reserved3 = 0
502pp_data->cap[11]->NotRange.DataIndex = 2
503pp_data->cap[11]->NotRange.Reserved4 = 2
504pp_data->cap[11]->NotButton.HasNull = 0
505pp_data->cap[11]->NotButton.Reserved4 = 0x000000
506pp_data->cap[11]->NotButton.LogicalMin = 0
507pp_data->cap[11]->NotButton.LogicalMax = 1
508pp_data->cap[11]->NotButton.PhysicalMin = 0
509pp_data->cap[11]->NotButton.PhysicalMax = 0
510pp_data->cap[11]->Units = 0
511pp_data->cap[11]->UnitsExp = 0
512
513# Feature hid_pp_cap struct:
514# Link Collections:
515pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
516pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
517pp_data->LinkCollectionArray[0]->Parent = 0
518pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
519pp_data->LinkCollectionArray[0]->NextSibling = 0
520pp_data->LinkCollectionArray[0]->FirstChild = 1
521pp_data->LinkCollectionArray[0]->CollectionType = 1
522pp_data->LinkCollectionArray[0]->IsAlias = 0
523pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
524pp_data->LinkCollectionArray[1]->LinkUsage = 0x0036
525pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x000C
526pp_data->LinkCollectionArray[1]->Parent = 0
527pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
528pp_data->LinkCollectionArray[1]->NextSibling = 0
529pp_data->LinkCollectionArray[1]->FirstChild = 0
530pp_data->LinkCollectionArray[1]->CollectionType = 2
531pp_data->LinkCollectionArray[1]->IsAlias = 0
532pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_expected.rpt_desc
new file mode 100644
index 0000000..363a8f5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_expected.rpt_desc
@@ -0,0 +1,16 @@
10x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x01, 0x09, 0xE9,
20x09, 0xEA, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x02,
30x81, 0x02, 0x09, 0xE2, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
40x95, 0x01, 0x81, 0x06, 0x75, 0x02, 0x95, 0x01, 0x81, 0x03,
50x09, 0x36, 0xA1, 0x02, 0x05, 0x09, 0x19, 0x01, 0x29, 0x02,
60x15, 0x01, 0x25, 0x02, 0x75, 0x02, 0x95, 0x01, 0x81, 0x40,
70x75, 0x01, 0x95, 0x01, 0x81, 0x03, 0xC0, 0x85, 0x02, 0x05,
80x0C, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95,
90x10, 0x81, 0x02, 0x85, 0x05, 0x09, 0x00, 0x15, 0x00, 0x25,
100x01, 0x75, 0x08, 0x95, 0x20, 0x81, 0x02, 0x85, 0x07, 0x09,
110x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x81,
120x02, 0x85, 0x03, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75,
130x01, 0x95, 0x10, 0x91, 0x02, 0x85, 0x04, 0x09, 0x00, 0x15,
140x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x24, 0x91, 0x02, 0x85,
150x06, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95,
160x24, 0x91, 0x02, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_real.rpt_desc
new file mode 100644
index 0000000..c784743
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_0A37_0001_000C_real.rpt_desc
@@ -0,0 +1,61 @@
1Usage Page (Consumer Devices) 05 0C
2Usage (Consumer Control) 09 01
3Collection (Application) A1 01
4 Report ID (1) 85 01
5 Logical Minimum (0) 15 00
6 Logical Maximum (1) 25 01
7 Usage (Volume Increment) 09 E9
8 Usage (Volume Decrement) 09 EA
9 Report Size (1) 75 01
10 Report Count (2) 95 02
11 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
12 Usage (Mute) 09 E2
13 Report Count (1) 95 01
14 Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
15 Usage (Undefined) 09 00
16 Report Count (2) 95 02
17 Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03
18 Usage (Function Buttons) 09 36
19 Collection (Logical) A1 02
20 Usage Page (Button) 05 09
21 Usage Minimum (Button 1) 19 01
22 Usage Maximum (Button 2) 29 02
23 Report Size (2) 75 02
24 Report Count (1) 95 01
25 Logical Minimum (1) 15 01
26 Logical Maximum (2) 25 02
27 Input (Data,Ary,Abs) 81 40
28 End Collection C0
29 Usage Page (Consumer Devices) 05 0C
30 Usage (Undefined) 09 00
31 Logical Minimum (0) 15 00
32 Logical Maximum (1) 25 01
33 Report Size (1) 75 01
34 Report Count (1) 95 01
35 Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03
36 Report ID (2) 85 02
37 Usage Page (Consumer Devices) 05 0C
38 Usage (Undefined) 09 00
39 Report Count (16) 95 10
40 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
41 Report ID (3) 85 03
42 Usage (Undefined) 09 00
43 Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
44 Report ID (4) 85 04
45 Usage (Undefined) 09 00
46 Report Size (8) 75 08
47 Report Count (36) 95 24
48 Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
49 Report ID (5) 85 05
50 Usage (Undefined) 09 00
51 Report Count (32) 95 20
52 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
53 Report ID (6) 85 06
54 Usage (Undefined) 09 00
55 Report Count (36) 95 24
56 Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
57 Report ID (7) 85 07
58 Usage (Undefined) 09 00
59 Report Count (32) 95 20
60 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
61End Collection C0
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C.pp_data
new file mode 100644
index 0000000..047445b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C.pp_data
@@ -0,0 +1,97 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xB010
4dev->manufacturer_string = "Logitech"
5dev->product_string = "Logitech Bluetooth Wireless Mouse"
6dev->release_number = 0x0000
7dev->interface_number = -1
8dev->usage = 0x0001
9dev->usage_page = 0x000C
10dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col02#8&1cf1c1b9&3&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0x000C
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 2
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 1
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 1
29pp_data->caps_info[2]->LastCap = 1
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0068
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0006
37pp_data->cap[0]->ReportID = 0x03
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 8
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x000C
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 0
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0020
70pp_data->cap[0]->NotRange.Reserved1 = 0x0020
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->NotButton.HasNull = 0
78pp_data->cap[0]->NotButton.Reserved4 = 0x000000
79pp_data->cap[0]->NotButton.LogicalMin = 0
80pp_data->cap[0]->NotButton.LogicalMax = 100
81pp_data->cap[0]->NotButton.PhysicalMin = 0
82pp_data->cap[0]->NotButton.PhysicalMax = 0
83pp_data->cap[0]->Units = 0
84pp_data->cap[0]->UnitsExp = 0
85
86# Output hid_pp_cap struct:
87# Feature hid_pp_cap struct:
88# Link Collections:
89pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
90pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
91pp_data->LinkCollectionArray[0]->Parent = 0
92pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
93pp_data->LinkCollectionArray[0]->NextSibling = 0
94pp_data->LinkCollectionArray[0]->FirstChild = 0
95pp_data->LinkCollectionArray[0]->CollectionType = 1
96pp_data->LinkCollectionArray[0]->IsAlias = 0
97pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_expected.rpt_desc
new file mode 100644
index 0000000..c80dd13
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_expected.rpt_desc
@@ -0,0 +1,3 @@
10x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x03, 0x05, 0x06,
20x09, 0x20, 0x15, 0x00, 0x25, 0x64, 0x75, 0x08, 0x95, 0x01,
30x81, 0x02, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_real.rpt_desc
new file mode 100644
index 0000000..ff019a9
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_000C_real.rpt_desc
@@ -0,0 +1,38 @@
1
2mac-hid-dump on  main ❯ ./mac-hid-dump
3mac-hid-dump:
4...
5046D B010: Unknown - Bluetooth Mouse M557
6DESCRIPTOR:
7 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
8 29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
9 09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
10 15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
11 08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
12 06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
13 00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
14 00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
15 01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
16 09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
17 08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
18 08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
19 01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
20 19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
21 00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
22 01 75 06 81 03 c0
23 (246 bytes)
24
25Parser output:
26
270x05, 0x0C, // Usage Page (Consumer)
280x09, 0x01, // Usage (Consumer Control)
290xA1, 0x01, // Collection (Application)
300x85, 0x03, // Report ID (3)
310x05, 0x06, // Usage Page (Generic Dev Ctrls)
320x09, 0x20, // Usage (Battery Strength)
330x15, 0x00, // Logical Minimum (0)
340x26, 0x64, 0x00, // Logical Maximum (100)
350x75, 0x08, // Report Size (8)
360x95, 0x01, // Report Count (1)
370x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
380xC0, // End Collection
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00.pp_data
new file mode 100644
index 0000000..13b27da
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00.pp_data
@@ -0,0 +1,139 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xB010
4dev->manufacturer_string = "Logitech"
5dev->product_string = "Logitech Bluetooth Wireless Mouse"
6dev->release_number = 0x0000
7dev->interface_number = -1
8dev->usage = 0x0001
9dev->usage_page = 0xFF00
10dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col03#8&1cf1c1b9&3&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0xFF00
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 7
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 2
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 7
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 2
29pp_data->caps_info[2]->LastCap = 2
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x00D0
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFF00
37pp_data->cap[0]->ReportID = 0x10
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 6
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 48
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0007
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0xFF00
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0001
70pp_data->cap[0]->NotRange.Reserved1 = 0x0001
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 255
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83pp_data->cap[1]->UsagePage = 0xFF00
84pp_data->cap[1]->ReportID = 0x10
85pp_data->cap[1]->BitPosition = 0
86pp_data->cap[1]->BitSize = 8
87pp_data->cap[1]->ReportCount = 6
88pp_data->cap[1]->BytePosition = 0x0001
89pp_data->cap[1]->BitCount = 48
90pp_data->cap[1]->BitField = 0x00
91pp_data->cap[1]->NextBytePosition = 0x0007
92pp_data->cap[1]->LinkCollection = 0x0000
93pp_data->cap[1]->LinkUsagePage = 0xFF00
94pp_data->cap[1]->LinkUsage = 0x0001
95pp_data->cap[1]->IsMultipleItemsForArray = 0
96pp_data->cap[1]->IsButtonCap = 1
97pp_data->cap[1]->IsPadding = 0
98pp_data->cap[1]->IsAbsolute = 1
99pp_data->cap[1]->IsRange = 0
100pp_data->cap[1]->IsAlias = 0
101pp_data->cap[1]->IsStringRange = 0
102pp_data->cap[1]->IsDesignatorRange = 0
103pp_data->cap[1]->Reserved1 = 0x000000
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
105pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
106pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
116pp_data->cap[1]->NotRange.Usage = 0x0001
117pp_data->cap[1]->NotRange.Reserved1 = 0x0001
118pp_data->cap[1]->NotRange.StringIndex = 0
119pp_data->cap[1]->NotRange.Reserved2 = 0
120pp_data->cap[1]->NotRange.DesignatorIndex = 0
121pp_data->cap[1]->NotRange.Reserved3 = 0
122pp_data->cap[1]->NotRange.DataIndex = 0
123pp_data->cap[1]->NotRange.Reserved4 = 0
124pp_data->cap[1]->Button.LogicalMin = 0
125pp_data->cap[1]->Button.LogicalMax = 255
126pp_data->cap[1]->Units = 0
127pp_data->cap[1]->UnitsExp = 0
128
129# Feature hid_pp_cap struct:
130# Link Collections:
131pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
132pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
133pp_data->LinkCollectionArray[0]->Parent = 0
134pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
135pp_data->LinkCollectionArray[0]->NextSibling = 0
136pp_data->LinkCollectionArray[0]->FirstChild = 0
137pp_data->LinkCollectionArray[0]->CollectionType = 1
138pp_data->LinkCollectionArray[0]->IsAlias = 0
139pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_expected.rpt_desc
new file mode 100644
index 0000000..812bd2a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_expected.rpt_desc
@@ -0,0 +1,4 @@
10x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x09,
20x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x06,
30x81, 0x00, 0x09, 0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
40x08, 0x95, 0x06, 0x91, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_real.rpt_desc
new file mode 100644
index 0000000..340d08d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0001_FF00_real.rpt_desc
@@ -0,0 +1,39 @@
1
2mac-hid-dump on  main ❯ ./mac-hid-dump
3mac-hid-dump:
4...
5046D B010: Unknown - Bluetooth Mouse M557
6DESCRIPTOR:
7 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
8 29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
9 09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
10 15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
11 08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
12 06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
13 00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
14 00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
15 01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
16 09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
17 08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
18 08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
19 01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
20 19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
21 00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
22 01 75 06 81 03 c0
23 (246 bytes)
24
25Parser output:
26
270x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
280x09, 0x01, // Usage (0x01)
290xA1, 0x01, // Collection (Application)
300x85, 0x10, // Report ID (16)
310x75, 0x08, // Report Size (8)
320x95, 0x06, // Report Count (6)
330x15, 0x00, // Logical Minimum (0)
340x26, 0xFF, 0x00, // Logical Maximum (255)
350x09, 0x01, // Usage (0x01)
360x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
370x09, 0x01, // Usage (0x01)
380x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
390xC0, // End Collection \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001.pp_data
new file mode 100644
index 0000000..1976766
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001.pp_data
@@ -0,0 +1,302 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xB010
4dev->manufacturer_string = "Logitech"
5dev->product_string = "Logitech Bluetooth Wireless Mouse"
6dev->release_number = 0x0000
7dev->interface_number = -1
8dev->usage = 0x0002
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col01#8&1cf1c1b9&3&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0002
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 5
20pp_data->caps_info[0]->NumberOfCaps = 5
21pp_data->caps_info[0]->ReportByteLength = 7
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 5
24pp_data->caps_info[1]->LastCap = 5
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 5
29pp_data->caps_info[2]->LastCap = 5
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0208
34pp_data->NumberLinkCollectionNodes = 2
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0009
37pp_data->cap[0]->ReportID = 0x02
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 8
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 8
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0001
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x0001
70pp_data->cap[0]->Range.UsageMax = 0x0008
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 7
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x0001
83pp_data->cap[1]->ReportID = 0x02
84pp_data->cap[1]->BitPosition = 4
85pp_data->cap[1]->BitSize = 12
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0003
88pp_data->cap[1]->BitCount = 12
89pp_data->cap[1]->BitField = 0x06
90pp_data->cap[1]->NextBytePosition = 0x0005
91pp_data->cap[1]->LinkCollection = 0x0001
92pp_data->cap[1]->LinkUsagePage = 0x0001
93pp_data->cap[1]->LinkUsage = 0x0001
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 0
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 0
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x0031
116pp_data->cap[1]->NotRange.Reserved1 = 0x0031
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 8
122pp_data->cap[1]->NotRange.Reserved4 = 8
123pp_data->cap[1]->NotButton.HasNull = 0
124pp_data->cap[1]->NotButton.Reserved4 = 0x000000
125pp_data->cap[1]->NotButton.LogicalMin = -2047
126pp_data->cap[1]->NotButton.LogicalMax = 2047
127pp_data->cap[1]->NotButton.PhysicalMin = 0
128pp_data->cap[1]->NotButton.PhysicalMax = 0
129pp_data->cap[1]->Units = 0
130pp_data->cap[1]->UnitsExp = 0
131
132pp_data->cap[2]->UsagePage = 0x0001
133pp_data->cap[2]->ReportID = 0x02
134pp_data->cap[2]->BitPosition = 0
135pp_data->cap[2]->BitSize = 12
136pp_data->cap[2]->ReportCount = 1
137pp_data->cap[2]->BytePosition = 0x0002
138pp_data->cap[2]->BitCount = 12
139pp_data->cap[2]->BitField = 0x06
140pp_data->cap[2]->NextBytePosition = 0x0004
141pp_data->cap[2]->LinkCollection = 0x0001
142pp_data->cap[2]->LinkUsagePage = 0x0001
143pp_data->cap[2]->LinkUsage = 0x0001
144pp_data->cap[2]->IsMultipleItemsForArray = 0
145pp_data->cap[2]->IsButtonCap = 0
146pp_data->cap[2]->IsPadding = 0
147pp_data->cap[2]->IsAbsolute = 0
148pp_data->cap[2]->IsRange = 0
149pp_data->cap[2]->IsAlias = 0
150pp_data->cap[2]->IsStringRange = 0
151pp_data->cap[2]->IsDesignatorRange = 0
152pp_data->cap[2]->Reserved1 = 0x000000
153pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
154pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
155pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
156pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
157pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
158pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
159pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
160pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
161pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
162pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
163pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
164pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
165pp_data->cap[2]->NotRange.Usage = 0x0030
166pp_data->cap[2]->NotRange.Reserved1 = 0x0030
167pp_data->cap[2]->NotRange.StringIndex = 0
168pp_data->cap[2]->NotRange.Reserved2 = 0
169pp_data->cap[2]->NotRange.DesignatorIndex = 0
170pp_data->cap[2]->NotRange.Reserved3 = 0
171pp_data->cap[2]->NotRange.DataIndex = 9
172pp_data->cap[2]->NotRange.Reserved4 = 9
173pp_data->cap[2]->NotButton.HasNull = 0
174pp_data->cap[2]->NotButton.Reserved4 = 0x000000
175pp_data->cap[2]->NotButton.LogicalMin = -2047
176pp_data->cap[2]->NotButton.LogicalMax = 2047
177pp_data->cap[2]->NotButton.PhysicalMin = 0
178pp_data->cap[2]->NotButton.PhysicalMax = 0
179pp_data->cap[2]->Units = 0
180pp_data->cap[2]->UnitsExp = 0
181
182pp_data->cap[3]->UsagePage = 0x0001
183pp_data->cap[3]->ReportID = 0x02
184pp_data->cap[3]->BitPosition = 0
185pp_data->cap[3]->BitSize = 8
186pp_data->cap[3]->ReportCount = 1
187pp_data->cap[3]->BytePosition = 0x0005
188pp_data->cap[3]->BitCount = 8
189pp_data->cap[3]->BitField = 0x06
190pp_data->cap[3]->NextBytePosition = 0x0006
191pp_data->cap[3]->LinkCollection = 0x0001
192pp_data->cap[3]->LinkUsagePage = 0x0001
193pp_data->cap[3]->LinkUsage = 0x0001
194pp_data->cap[3]->IsMultipleItemsForArray = 0
195pp_data->cap[3]->IsButtonCap = 0
196pp_data->cap[3]->IsPadding = 0
197pp_data->cap[3]->IsAbsolute = 0
198pp_data->cap[3]->IsRange = 0
199pp_data->cap[3]->IsAlias = 0
200pp_data->cap[3]->IsStringRange = 0
201pp_data->cap[3]->IsDesignatorRange = 0
202pp_data->cap[3]->Reserved1 = 0x000000
203pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
204pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
205pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
206pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
207pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
208pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
209pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
210pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
211pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
212pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
213pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
214pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
215pp_data->cap[3]->NotRange.Usage = 0x0038
216pp_data->cap[3]->NotRange.Reserved1 = 0x0038
217pp_data->cap[3]->NotRange.StringIndex = 0
218pp_data->cap[3]->NotRange.Reserved2 = 0
219pp_data->cap[3]->NotRange.DesignatorIndex = 0
220pp_data->cap[3]->NotRange.Reserved3 = 0
221pp_data->cap[3]->NotRange.DataIndex = 10
222pp_data->cap[3]->NotRange.Reserved4 = 10
223pp_data->cap[3]->NotButton.HasNull = 0
224pp_data->cap[3]->NotButton.Reserved4 = 0x000000
225pp_data->cap[3]->NotButton.LogicalMin = -127
226pp_data->cap[3]->NotButton.LogicalMax = 127
227pp_data->cap[3]->NotButton.PhysicalMin = 0
228pp_data->cap[3]->NotButton.PhysicalMax = 0
229pp_data->cap[3]->Units = 0
230pp_data->cap[3]->UnitsExp = 0
231
232pp_data->cap[4]->UsagePage = 0x000C
233pp_data->cap[4]->ReportID = 0x02
234pp_data->cap[4]->BitPosition = 0
235pp_data->cap[4]->BitSize = 8
236pp_data->cap[4]->ReportCount = 1
237pp_data->cap[4]->BytePosition = 0x0006
238pp_data->cap[4]->BitCount = 8
239pp_data->cap[4]->BitField = 0x06
240pp_data->cap[4]->NextBytePosition = 0x0007
241pp_data->cap[4]->LinkCollection = 0x0001
242pp_data->cap[4]->LinkUsagePage = 0x0001
243pp_data->cap[4]->LinkUsage = 0x0001
244pp_data->cap[4]->IsMultipleItemsForArray = 0
245pp_data->cap[4]->IsButtonCap = 0
246pp_data->cap[4]->IsPadding = 0
247pp_data->cap[4]->IsAbsolute = 0
248pp_data->cap[4]->IsRange = 0
249pp_data->cap[4]->IsAlias = 0
250pp_data->cap[4]->IsStringRange = 0
251pp_data->cap[4]->IsDesignatorRange = 0
252pp_data->cap[4]->Reserved1 = 0x000000
253pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
254pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
255pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
256pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
257pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
258pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
259pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
260pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
261pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
262pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
263pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
264pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
265pp_data->cap[4]->NotRange.Usage = 0x0238
266pp_data->cap[4]->NotRange.Reserved1 = 0x0238
267pp_data->cap[4]->NotRange.StringIndex = 0
268pp_data->cap[4]->NotRange.Reserved2 = 0
269pp_data->cap[4]->NotRange.DesignatorIndex = 0
270pp_data->cap[4]->NotRange.Reserved3 = 0
271pp_data->cap[4]->NotRange.DataIndex = 11
272pp_data->cap[4]->NotRange.Reserved4 = 11
273pp_data->cap[4]->NotButton.HasNull = 0
274pp_data->cap[4]->NotButton.Reserved4 = 0x000000
275pp_data->cap[4]->NotButton.LogicalMin = -127
276pp_data->cap[4]->NotButton.LogicalMax = 127
277pp_data->cap[4]->NotButton.PhysicalMin = 0
278pp_data->cap[4]->NotButton.PhysicalMax = 0
279pp_data->cap[4]->Units = 0
280pp_data->cap[4]->UnitsExp = 0
281
282# Output hid_pp_cap struct:
283# Feature hid_pp_cap struct:
284# Link Collections:
285pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
286pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
287pp_data->LinkCollectionArray[0]->Parent = 0
288pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
289pp_data->LinkCollectionArray[0]->NextSibling = 0
290pp_data->LinkCollectionArray[0]->FirstChild = 1
291pp_data->LinkCollectionArray[0]->CollectionType = 1
292pp_data->LinkCollectionArray[0]->IsAlias = 0
293pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
294pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
295pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
296pp_data->LinkCollectionArray[1]->Parent = 0
297pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
298pp_data->LinkCollectionArray[1]->NextSibling = 0
299pp_data->LinkCollectionArray[1]->FirstChild = 0
300pp_data->LinkCollectionArray[1]->CollectionType = 0
301pp_data->LinkCollectionArray[1]->IsAlias = 0
302pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_expected.rpt_desc
new file mode 100644
index 0000000..d782fa1
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_expected.rpt_desc
@@ -0,0 +1,8 @@
10x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
20x85, 0x02, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, 0x00,
30x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x05, 0x01,
40x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xF8, 0x26, 0xFF, 0x07,
50x75, 0x0C, 0x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81,
60x25, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0x05, 0x0C,
70x0A, 0x38, 0x02, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95,
80x01, 0x81, 0x06, 0xC0, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_real.rpt_desc
new file mode 100644
index 0000000..483f659
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_0001_real.rpt_desc
@@ -0,0 +1,61 @@
1
2mac-hid-dump on  main ❯ ./mac-hid-dump
3mac-hid-dump:
4...
5046D B010: Unknown - Bluetooth Mouse M557
6DESCRIPTOR:
7 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
8 29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
9 09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
10 15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
11 08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
12 06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
13 00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
14 00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
15 01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
16 09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
17 08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
18 08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
19 01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
20 19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
21 00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
22 01 75 06 81 03 c0
23 (246 bytes)
24
25Parser output:
26
270x05, 0x01, // Usage Page (Generic Desktop Ctrls)
280x09, 0x02, // Usage (Mouse)
290xA1, 0x01, // Collection (Application)
300x85, 0x02, // Report ID (2)
310x09, 0x01, // Usage (Pointer)
320xA1, 0x00, // Collection (Physical)
330x05, 0x09, // Usage Page (Button)
340x19, 0x01, // Usage Minimum (0x01)
350x29, 0x08, // Usage Maximum (0x08)
360x15, 0x00, // Logical Minimum (0)
370x25, 0x01, // Logical Maximum (1)
380x75, 0x01, // Report Size (1)
390x95, 0x08, // Report Count (8)
400x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
410x05, 0x01, // Usage Page (Generic Desktop Ctrls)
420x09, 0x30, // Usage (X)
430x09, 0x31, // Usage (Y)
440x16, 0x01, 0xF8, // Logical Minimum (-2047)
450x26, 0xFF, 0x07, // Logical Maximum (2047)
460x75, 0x0C, // Report Size (12)
470x95, 0x02, // Report Count (2)
480x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
490x09, 0x38, // Usage (Wheel)
500x15, 0x81, // Logical Minimum (-127)
510x25, 0x7F, // Logical Maximum (127)
520x75, 0x08, // Report Size (8)
530x95, 0x01, // Report Count (1)
540x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
550x05, 0x0C, // Usage Page (Consumer)
560x0A, 0x38, 0x02, // Usage (AC Pan)
570x75, 0x08, // Report Size (8)
580x95, 0x01, // Report Count (1)
590x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
600xC0, // End Collection
610xC0, // End Collection
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00.pp_data
new file mode 100644
index 0000000..0dc64b2
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00.pp_data
@@ -0,0 +1,139 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xB010
4dev->manufacturer_string = "Logitech"
5dev->product_string = "Logitech Bluetooth Wireless Mouse"
6dev->release_number = 0x0000
7dev->interface_number = -1
8dev->usage = 0x0002
9dev->usage_page = 0xFF00
10dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col04#8&1cf1c1b9&3&0003#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0002
15pp_data->UsagePage = 0xFF00
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 20
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 2
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 20
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 2
29pp_data->caps_info[2]->LastCap = 2
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x00D0
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFF00
37pp_data->cap[0]->ReportID = 0x11
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 19
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 152
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0014
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0xFF00
47pp_data->cap[0]->LinkUsage = 0x0002
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0002
70pp_data->cap[0]->NotRange.Reserved1 = 0x0002
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 255
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83pp_data->cap[1]->UsagePage = 0xFF00
84pp_data->cap[1]->ReportID = 0x11
85pp_data->cap[1]->BitPosition = 0
86pp_data->cap[1]->BitSize = 8
87pp_data->cap[1]->ReportCount = 19
88pp_data->cap[1]->BytePosition = 0x0001
89pp_data->cap[1]->BitCount = 152
90pp_data->cap[1]->BitField = 0x00
91pp_data->cap[1]->NextBytePosition = 0x0014
92pp_data->cap[1]->LinkCollection = 0x0000
93pp_data->cap[1]->LinkUsagePage = 0xFF00
94pp_data->cap[1]->LinkUsage = 0x0002
95pp_data->cap[1]->IsMultipleItemsForArray = 0
96pp_data->cap[1]->IsButtonCap = 1
97pp_data->cap[1]->IsPadding = 0
98pp_data->cap[1]->IsAbsolute = 1
99pp_data->cap[1]->IsRange = 0
100pp_data->cap[1]->IsAlias = 0
101pp_data->cap[1]->IsStringRange = 0
102pp_data->cap[1]->IsDesignatorRange = 0
103pp_data->cap[1]->Reserved1 = 0x000000
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
105pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
106pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
116pp_data->cap[1]->NotRange.Usage = 0x0002
117pp_data->cap[1]->NotRange.Reserved1 = 0x0002
118pp_data->cap[1]->NotRange.StringIndex = 0
119pp_data->cap[1]->NotRange.Reserved2 = 0
120pp_data->cap[1]->NotRange.DesignatorIndex = 0
121pp_data->cap[1]->NotRange.Reserved3 = 0
122pp_data->cap[1]->NotRange.DataIndex = 0
123pp_data->cap[1]->NotRange.Reserved4 = 0
124pp_data->cap[1]->Button.LogicalMin = 0
125pp_data->cap[1]->Button.LogicalMax = 255
126pp_data->cap[1]->Units = 0
127pp_data->cap[1]->UnitsExp = 0
128
129# Feature hid_pp_cap struct:
130# Link Collections:
131pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
132pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
133pp_data->LinkCollectionArray[0]->Parent = 0
134pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
135pp_data->LinkCollectionArray[0]->NextSibling = 0
136pp_data->LinkCollectionArray[0]->FirstChild = 0
137pp_data->LinkCollectionArray[0]->CollectionType = 1
138pp_data->LinkCollectionArray[0]->IsAlias = 0
139pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_expected.rpt_desc
new file mode 100644
index 0000000..b1654e7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_expected.rpt_desc
@@ -0,0 +1,4 @@
10x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, 0x01, 0x85, 0x11, 0x09,
20x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x13,
30x81, 0x00, 0x09, 0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
40x08, 0x95, 0x13, 0x91, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_real.rpt_desc
new file mode 100644
index 0000000..8b8dbfc
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0002_FF00_real.rpt_desc
@@ -0,0 +1,39 @@
1
2mac-hid-dump on  main ❯ ./mac-hid-dump
3mac-hid-dump:
4...
5046D B010: Unknown - Bluetooth Mouse M557
6DESCRIPTOR:
7 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
8 29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
9 09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
10 15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
11 08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
12 06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
13 00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
14 00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
15 01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
16 09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
17 08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
18 08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
19 01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
20 19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
21 00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
22 01 75 06 81 03 c0
23 (246 bytes)
24
25Parser output:
26
270x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
280x09, 0x02, // Usage (0x02)
290xA1, 0x01, // Collection (Application)
300x85, 0x11, // Report ID (17)
310x75, 0x08, // Report Size (8)
320x95, 0x13, // Report Count (19)
330x15, 0x00, // Logical Minimum (0)
340x26, 0xFF, 0x00, // Logical Maximum (255)
350x09, 0x02, // Usage (0x02)
360x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
370x09, 0x02, // Usage (0x02)
380x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
390xC0, // End Collection \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001.pp_data
new file mode 100644
index 0000000..7682a0d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001.pp_data
@@ -0,0 +1,185 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xB010
4dev->manufacturer_string = "Logitech"
5dev->product_string = "Logitech Bluetooth Wireless Mouse"
6dev->release_number = 0x0000
7dev->interface_number = -1
8dev->usage = 0x0006
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col05#8&1cf1c1b9&3&0004#{4d1e55b2-f16f-11cf-88cb-001111000030}\kbd"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0006
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 2
20pp_data->caps_info[0]->NumberOfCaps = 2
21pp_data->caps_info[0]->ReportByteLength = 9
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 2
24pp_data->caps_info[1]->LastCap = 3
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 2
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 3
29pp_data->caps_info[2]->LastCap = 3
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0138
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0007
37pp_data->cap[0]->ReportID = 0x04
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 8
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 8
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0006
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x00E0
70pp_data->cap[0]->Range.UsageMax = 0x00E7
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 7
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x0007
83pp_data->cap[1]->ReportID = 0x04
84pp_data->cap[1]->BitPosition = 0
85pp_data->cap[1]->BitSize = 8
86pp_data->cap[1]->ReportCount = 6
87pp_data->cap[1]->BytePosition = 0x0003
88pp_data->cap[1]->BitCount = 48
89pp_data->cap[1]->BitField = 0x00
90pp_data->cap[1]->NextBytePosition = 0x0009
91pp_data->cap[1]->LinkCollection = 0x0000
92pp_data->cap[1]->LinkUsagePage = 0x0001
93pp_data->cap[1]->LinkUsage = 0x0006
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 1
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 1
98pp_data->cap[1]->IsRange = 1
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->Range.UsageMin = 0x0000
116pp_data->cap[1]->Range.UsageMax = 0x00FF
117pp_data->cap[1]->Range.StringMin = 0
118pp_data->cap[1]->Range.StringMax = 0
119pp_data->cap[1]->Range.DesignatorMin = 0
120pp_data->cap[1]->Range.DesignatorMax = 0
121pp_data->cap[1]->Range.DataIndexMin = 8
122pp_data->cap[1]->Range.DataIndexMax = 263
123pp_data->cap[1]->Button.LogicalMin = 0
124pp_data->cap[1]->Button.LogicalMax = 255
125pp_data->cap[1]->Units = 0
126pp_data->cap[1]->UnitsExp = 0
127
128# Output hid_pp_cap struct:
129pp_data->cap[2]->UsagePage = 0x0008
130pp_data->cap[2]->ReportID = 0x04
131pp_data->cap[2]->BitPosition = 0
132pp_data->cap[2]->BitSize = 1
133pp_data->cap[2]->ReportCount = 5
134pp_data->cap[2]->BytePosition = 0x0001
135pp_data->cap[2]->BitCount = 5
136pp_data->cap[2]->BitField = 0x02
137pp_data->cap[2]->NextBytePosition = 0x0002
138pp_data->cap[2]->LinkCollection = 0x0000
139pp_data->cap[2]->LinkUsagePage = 0x0001
140pp_data->cap[2]->LinkUsage = 0x0006
141pp_data->cap[2]->IsMultipleItemsForArray = 0
142pp_data->cap[2]->IsButtonCap = 1
143pp_data->cap[2]->IsPadding = 0
144pp_data->cap[2]->IsAbsolute = 1
145pp_data->cap[2]->IsRange = 1
146pp_data->cap[2]->IsAlias = 0
147pp_data->cap[2]->IsStringRange = 0
148pp_data->cap[2]->IsDesignatorRange = 0
149pp_data->cap[2]->Reserved1 = 0x000000
150pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
151pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
152pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
153pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
154pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
155pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
156pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
157pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
158pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
159pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
160pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
161pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
162pp_data->cap[2]->Range.UsageMin = 0x0001
163pp_data->cap[2]->Range.UsageMax = 0x0005
164pp_data->cap[2]->Range.StringMin = 0
165pp_data->cap[2]->Range.StringMax = 0
166pp_data->cap[2]->Range.DesignatorMin = 0
167pp_data->cap[2]->Range.DesignatorMax = 0
168pp_data->cap[2]->Range.DataIndexMin = 0
169pp_data->cap[2]->Range.DataIndexMax = 4
170pp_data->cap[2]->Button.LogicalMin = 0
171pp_data->cap[2]->Button.LogicalMax = 0
172pp_data->cap[2]->Units = 0
173pp_data->cap[2]->UnitsExp = 0
174
175# Feature hid_pp_cap struct:
176# Link Collections:
177pp_data->LinkCollectionArray[0]->LinkUsage = 0x0006
178pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
179pp_data->LinkCollectionArray[0]->Parent = 0
180pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
181pp_data->LinkCollectionArray[0]->NextSibling = 0
182pp_data->LinkCollectionArray[0]->FirstChild = 0
183pp_data->LinkCollectionArray[0]->CollectionType = 1
184pp_data->LinkCollectionArray[0]->IsAlias = 0
185pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_expected.rpt_desc
new file mode 100644
index 0000000..1ec0b16
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_expected.rpt_desc
@@ -0,0 +1,7 @@
10x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x85, 0x04, 0x05, 0x07,
20x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
30x95, 0x08, 0x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03,
40x19, 0x00, 0x29, 0xFF, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
50x08, 0x95, 0x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29,
60x05, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x05, 0x91,
70x02, 0x75, 0x03, 0x95, 0x01, 0x91, 0x03, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_real.rpt_desc
new file mode 100644
index 0000000..59ab03d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_B010_0006_0001_real.rpt_desc
@@ -0,0 +1,58 @@
1
2mac-hid-dump on  main ❯ ./mac-hid-dump
3mac-hid-dump:
4...
5046D B010: Unknown - Bluetooth Mouse M557
6DESCRIPTOR:
7 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
8 29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
9 09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
10 15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
11 08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
12 06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
13 00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
14 00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
15 01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
16 09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
17 08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
18 08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
19 01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
20 19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
21 00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
22 01 75 06 81 03 c0
23 (246 bytes)
24
25Parser output:
260x05, 0x01, // Usage Page (Generic Desktop Ctrls)
270x09, 0x06, // Usage (Keyboard)
280xA1, 0x01, // Collection (Application)
290x85, 0x04, // Report ID (4)
300x75, 0x01, // Report Size (1)
310x95, 0x08, // Report Count (8)
320x05, 0x07, // Usage Page (Kbrd/Keypad)
330x19, 0xE0, // Usage Minimum (0xE0)
340x29, 0xE7, // Usage Maximum (0xE7)
350x15, 0x00, // Logical Minimum (0)
360x25, 0x01, // Logical Maximum (1)
370x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
380x95, 0x01, // Report Count (1)
390x75, 0x08, // Report Size (8)
400x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
410x95, 0x05, // Report Count (5)
420x75, 0x01, // Report Size (1)
430x05, 0x08, // Usage Page (LEDs)
440x19, 0x01, // Usage Minimum (Num Lock)
450x29, 0x05, // Usage Maximum (Kana)
460x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
470x95, 0x01, // Report Count (1)
480x75, 0x03, // Report Size (3)
490x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
500x95, 0x06, // Report Count (6)
510x75, 0x08, // Report Size (8)
520x15, 0x00, // Logical Minimum (0)
530x26, 0xFF, 0x00, // Logical Maximum (255)
540x05, 0x07, // Usage Page (Kbrd/Keypad)
550x19, 0x00, // Usage Minimum (0x00)
560x29, 0xFF, // Usage Maximum (0xFF)
570x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
580xC0, // End Collection \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001.pp_data
new file mode 100644
index 0000000..3e9fcea
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001.pp_data
@@ -0,0 +1,252 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC077
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Optical Mouse"
6dev->release_number = 0x7200
7dev->interface_number = -1
8dev->usage = 0x0002
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#vid_046d&pid_c077#7&1875dbae&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0002
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 4
20pp_data->caps_info[0]->NumberOfCaps = 4
21pp_data->caps_info[0]->ReportByteLength = 5
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 4
24pp_data->caps_info[1]->LastCap = 4
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 4
29pp_data->caps_info[2]->LastCap = 4
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x01A0
34pp_data->NumberLinkCollectionNodes = 2
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0009
37pp_data->cap[0]->ReportID = 0x00
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 8
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 8
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0001
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x0001
70pp_data->cap[0]->Range.UsageMax = 0x0003
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 2
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x0001
83pp_data->cap[1]->ReportID = 0x00
84pp_data->cap[1]->BitPosition = 0
85pp_data->cap[1]->BitSize = 8
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0004
88pp_data->cap[1]->BitCount = 8
89pp_data->cap[1]->BitField = 0x06
90pp_data->cap[1]->NextBytePosition = 0x0005
91pp_data->cap[1]->LinkCollection = 0x0001
92pp_data->cap[1]->LinkUsagePage = 0x0001
93pp_data->cap[1]->LinkUsage = 0x0001
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 0
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 0
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x0038
116pp_data->cap[1]->NotRange.Reserved1 = 0x0038
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 3
122pp_data->cap[1]->NotRange.Reserved4 = 3
123pp_data->cap[1]->NotButton.HasNull = 0
124pp_data->cap[1]->NotButton.Reserved4 = 0x000000
125pp_data->cap[1]->NotButton.LogicalMin = -127
126pp_data->cap[1]->NotButton.LogicalMax = 127
127pp_data->cap[1]->NotButton.PhysicalMin = 0
128pp_data->cap[1]->NotButton.PhysicalMax = 0
129pp_data->cap[1]->Units = 0
130pp_data->cap[1]->UnitsExp = 0
131
132pp_data->cap[2]->UsagePage = 0x0001
133pp_data->cap[2]->ReportID = 0x00
134pp_data->cap[2]->BitPosition = 0
135pp_data->cap[2]->BitSize = 8
136pp_data->cap[2]->ReportCount = 1
137pp_data->cap[2]->BytePosition = 0x0003
138pp_data->cap[2]->BitCount = 8
139pp_data->cap[2]->BitField = 0x06
140pp_data->cap[2]->NextBytePosition = 0x0004
141pp_data->cap[2]->LinkCollection = 0x0001
142pp_data->cap[2]->LinkUsagePage = 0x0001
143pp_data->cap[2]->LinkUsage = 0x0001
144pp_data->cap[2]->IsMultipleItemsForArray = 0
145pp_data->cap[2]->IsButtonCap = 0
146pp_data->cap[2]->IsPadding = 0
147pp_data->cap[2]->IsAbsolute = 0
148pp_data->cap[2]->IsRange = 0
149pp_data->cap[2]->IsAlias = 0
150pp_data->cap[2]->IsStringRange = 0
151pp_data->cap[2]->IsDesignatorRange = 0
152pp_data->cap[2]->Reserved1 = 0x000000
153pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
154pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
155pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
156pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
157pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
158pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
159pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
160pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
161pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
162pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
163pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
164pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
165pp_data->cap[2]->NotRange.Usage = 0x0031
166pp_data->cap[2]->NotRange.Reserved1 = 0x0031
167pp_data->cap[2]->NotRange.StringIndex = 0
168pp_data->cap[2]->NotRange.Reserved2 = 0
169pp_data->cap[2]->NotRange.DesignatorIndex = 0
170pp_data->cap[2]->NotRange.Reserved3 = 0
171pp_data->cap[2]->NotRange.DataIndex = 4
172pp_data->cap[2]->NotRange.Reserved4 = 4
173pp_data->cap[2]->NotButton.HasNull = 0
174pp_data->cap[2]->NotButton.Reserved4 = 0x000000
175pp_data->cap[2]->NotButton.LogicalMin = -127
176pp_data->cap[2]->NotButton.LogicalMax = 127
177pp_data->cap[2]->NotButton.PhysicalMin = 0
178pp_data->cap[2]->NotButton.PhysicalMax = 0
179pp_data->cap[2]->Units = 0
180pp_data->cap[2]->UnitsExp = 0
181
182pp_data->cap[3]->UsagePage = 0x0001
183pp_data->cap[3]->ReportID = 0x00
184pp_data->cap[3]->BitPosition = 0
185pp_data->cap[3]->BitSize = 8
186pp_data->cap[3]->ReportCount = 1
187pp_data->cap[3]->BytePosition = 0x0002
188pp_data->cap[3]->BitCount = 8
189pp_data->cap[3]->BitField = 0x06
190pp_data->cap[3]->NextBytePosition = 0x0003
191pp_data->cap[3]->LinkCollection = 0x0001
192pp_data->cap[3]->LinkUsagePage = 0x0001
193pp_data->cap[3]->LinkUsage = 0x0001
194pp_data->cap[3]->IsMultipleItemsForArray = 0
195pp_data->cap[3]->IsButtonCap = 0
196pp_data->cap[3]->IsPadding = 0
197pp_data->cap[3]->IsAbsolute = 0
198pp_data->cap[3]->IsRange = 0
199pp_data->cap[3]->IsAlias = 0
200pp_data->cap[3]->IsStringRange = 0
201pp_data->cap[3]->IsDesignatorRange = 0
202pp_data->cap[3]->Reserved1 = 0x000000
203pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
204pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
205pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
206pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
207pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
208pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
209pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
210pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
211pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
212pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
213pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
214pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
215pp_data->cap[3]->NotRange.Usage = 0x0030
216pp_data->cap[3]->NotRange.Reserved1 = 0x0030
217pp_data->cap[3]->NotRange.StringIndex = 0
218pp_data->cap[3]->NotRange.Reserved2 = 0
219pp_data->cap[3]->NotRange.DesignatorIndex = 0
220pp_data->cap[3]->NotRange.Reserved3 = 0
221pp_data->cap[3]->NotRange.DataIndex = 5
222pp_data->cap[3]->NotRange.Reserved4 = 5
223pp_data->cap[3]->NotButton.HasNull = 0
224pp_data->cap[3]->NotButton.Reserved4 = 0x000000
225pp_data->cap[3]->NotButton.LogicalMin = -127
226pp_data->cap[3]->NotButton.LogicalMax = 127
227pp_data->cap[3]->NotButton.PhysicalMin = 0
228pp_data->cap[3]->NotButton.PhysicalMax = 0
229pp_data->cap[3]->Units = 0
230pp_data->cap[3]->UnitsExp = 0
231
232# Output hid_pp_cap struct:
233# Feature hid_pp_cap struct:
234# Link Collections:
235pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
236pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
237pp_data->LinkCollectionArray[0]->Parent = 0
238pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
239pp_data->LinkCollectionArray[0]->NextSibling = 0
240pp_data->LinkCollectionArray[0]->FirstChild = 1
241pp_data->LinkCollectionArray[0]->CollectionType = 1
242pp_data->LinkCollectionArray[0]->IsAlias = 0
243pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
244pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
245pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
246pp_data->LinkCollectionArray[1]->Parent = 0
247pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
248pp_data->LinkCollectionArray[1]->NextSibling = 0
249pp_data->LinkCollectionArray[1]->FirstChild = 0
250pp_data->LinkCollectionArray[1]->CollectionType = 0
251pp_data->LinkCollectionArray[1]->IsAlias = 0
252pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_expected.rpt_desc
new file mode 100644
index 0000000..7e144b4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_expected.rpt_desc
@@ -0,0 +1,5 @@
10x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
20x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01,
30x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30,
40x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08,
50x95, 0x03, 0x81, 0x06, 0xC0, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_real.rpt_desc
new file mode 100644
index 0000000..7604c55
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C077_0002_0001_real.rpt_desc
@@ -0,0 +1,24 @@
1Usage Page (Generic Desktop) 05 01
2Usage (Mouse) 09 02
3Collection (Application) A1 01
4 Usage (Pointer) 09 01
5 Collection (Physical) A1 00
6 Usage Page (Button) 05 09
7 Usage Minimum (Button 1) 19 01
8 Usage Maximum (Button 3) 29 03
9 Logical Minimum (0) 15 00
10 Logical Maximum (1) 25 01
11 Report Count (8) 95 08
12 Report Size (1) 75 01
13 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
14 Usage Page (Generic Desktop) 05 01
15 Usage (X) 09 30
16 Usage (Y) 09 31
17 Usage (Wheel) 09 38
18 Logical Minimum (-127) 15 81
19 Logical Maximum (127) 25 7F
20 Report Size (8) 75 08
21 Report Count (3) 95 03
22 Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
23 End Collection C0
24End Collection C0
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001.pp_data
new file mode 100644
index 0000000..0f70d06
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001.pp_data
@@ -0,0 +1,520 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC283
4dev->manufacturer_string = "Logitech Inc."
5dev->product_string = "WingMan Force 3D"
6dev->release_number = 0x0106
7dev->interface_number = -1
8dev->usage = 0x0004
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#vid_046d&pid_c283#7&d7fb4bf&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0004
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 8
20pp_data->caps_info[0]->NumberOfCaps = 8
21pp_data->caps_info[0]->ReportByteLength = 8
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 8
24pp_data->caps_info[1]->LastCap = 9
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 9
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 9
29pp_data->caps_info[2]->LastCap = 9
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x03A8
34pp_data->NumberLinkCollectionNodes = 4
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0001
37pp_data->cap[0]->ReportID = 0x00
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0002
42pp_data->cap[0]->BitCount = 8
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0003
45pp_data->cap[0]->LinkCollection = 0x0002
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 0
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0031
70pp_data->cap[0]->NotRange.Reserved1 = 0x0031
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->NotButton.HasNull = 0
78pp_data->cap[0]->NotButton.Reserved4 = 0x000000
79pp_data->cap[0]->NotButton.LogicalMin = 0
80pp_data->cap[0]->NotButton.LogicalMax = 255
81pp_data->cap[0]->NotButton.PhysicalMin = 0
82pp_data->cap[0]->NotButton.PhysicalMax = 255
83pp_data->cap[0]->Units = 0
84pp_data->cap[0]->UnitsExp = 0
85
86pp_data->cap[1]->UsagePage = 0x0001
87pp_data->cap[1]->ReportID = 0x00
88pp_data->cap[1]->BitPosition = 0
89pp_data->cap[1]->BitSize = 8
90pp_data->cap[1]->ReportCount = 1
91pp_data->cap[1]->BytePosition = 0x0001
92pp_data->cap[1]->BitCount = 8
93pp_data->cap[1]->BitField = 0x02
94pp_data->cap[1]->NextBytePosition = 0x0002
95pp_data->cap[1]->LinkCollection = 0x0002
96pp_data->cap[1]->LinkUsagePage = 0x0001
97pp_data->cap[1]->LinkUsage = 0x0001
98pp_data->cap[1]->IsMultipleItemsForArray = 0
99pp_data->cap[1]->IsButtonCap = 0
100pp_data->cap[1]->IsPadding = 0
101pp_data->cap[1]->IsAbsolute = 1
102pp_data->cap[1]->IsRange = 0
103pp_data->cap[1]->IsAlias = 0
104pp_data->cap[1]->IsStringRange = 0
105pp_data->cap[1]->IsDesignatorRange = 0
106pp_data->cap[1]->Reserved1 = 0x000000
107pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
116pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
117pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
118pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
119pp_data->cap[1]->NotRange.Usage = 0x0030
120pp_data->cap[1]->NotRange.Reserved1 = 0x0030
121pp_data->cap[1]->NotRange.StringIndex = 0
122pp_data->cap[1]->NotRange.Reserved2 = 0
123pp_data->cap[1]->NotRange.DesignatorIndex = 0
124pp_data->cap[1]->NotRange.Reserved3 = 0
125pp_data->cap[1]->NotRange.DataIndex = 1
126pp_data->cap[1]->NotRange.Reserved4 = 1
127pp_data->cap[1]->NotButton.HasNull = 0
128pp_data->cap[1]->NotButton.Reserved4 = 0x000000
129pp_data->cap[1]->NotButton.LogicalMin = 0
130pp_data->cap[1]->NotButton.LogicalMax = 255
131pp_data->cap[1]->NotButton.PhysicalMin = 0
132pp_data->cap[1]->NotButton.PhysicalMax = 255
133pp_data->cap[1]->Units = 0
134pp_data->cap[1]->UnitsExp = 0
135
136pp_data->cap[2]->UsagePage = 0xFF00
137pp_data->cap[2]->ReportID = 0x00
138pp_data->cap[2]->BitPosition = 0
139pp_data->cap[2]->BitSize = 4
140pp_data->cap[2]->ReportCount = 1
141pp_data->cap[2]->BytePosition = 0x0003
142pp_data->cap[2]->BitCount = 4
143pp_data->cap[2]->BitField = 0x02
144pp_data->cap[2]->NextBytePosition = 0x0004
145pp_data->cap[2]->LinkCollection = 0x0002
146pp_data->cap[2]->LinkUsagePage = 0x0001
147pp_data->cap[2]->LinkUsage = 0x0001
148pp_data->cap[2]->IsMultipleItemsForArray = 0
149pp_data->cap[2]->IsButtonCap = 0
150pp_data->cap[2]->IsPadding = 0
151pp_data->cap[2]->IsAbsolute = 1
152pp_data->cap[2]->IsRange = 0
153pp_data->cap[2]->IsAlias = 0
154pp_data->cap[2]->IsStringRange = 0
155pp_data->cap[2]->IsDesignatorRange = 0
156pp_data->cap[2]->Reserved1 = 0x000000
157pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
158pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
159pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
160pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
161pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
162pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
163pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
164pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
165pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
166pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
167pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
168pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
169pp_data->cap[2]->NotRange.Usage = 0x0001
170pp_data->cap[2]->NotRange.Reserved1 = 0x0001
171pp_data->cap[2]->NotRange.StringIndex = 0
172pp_data->cap[2]->NotRange.Reserved2 = 0
173pp_data->cap[2]->NotRange.DesignatorIndex = 0
174pp_data->cap[2]->NotRange.Reserved3 = 0
175pp_data->cap[2]->NotRange.DataIndex = 2
176pp_data->cap[2]->NotRange.Reserved4 = 2
177pp_data->cap[2]->NotButton.HasNull = 0
178pp_data->cap[2]->NotButton.Reserved4 = 0x000000
179pp_data->cap[2]->NotButton.LogicalMin = 0
180pp_data->cap[2]->NotButton.LogicalMax = 15
181pp_data->cap[2]->NotButton.PhysicalMin = 0
182pp_data->cap[2]->NotButton.PhysicalMax = 255
183pp_data->cap[2]->Units = 0
184pp_data->cap[2]->UnitsExp = 0
185
186pp_data->cap[3]->UsagePage = 0x0001
187pp_data->cap[3]->ReportID = 0x00
188pp_data->cap[3]->BitPosition = 4
189pp_data->cap[3]->BitSize = 4
190pp_data->cap[3]->ReportCount = 1
191pp_data->cap[3]->BytePosition = 0x0003
192pp_data->cap[3]->BitCount = 4
193pp_data->cap[3]->BitField = 0x42
194pp_data->cap[3]->NextBytePosition = 0x0004
195pp_data->cap[3]->LinkCollection = 0x0002
196pp_data->cap[3]->LinkUsagePage = 0x0001
197pp_data->cap[3]->LinkUsage = 0x0001
198pp_data->cap[3]->IsMultipleItemsForArray = 0
199pp_data->cap[3]->IsButtonCap = 0
200pp_data->cap[3]->IsPadding = 0
201pp_data->cap[3]->IsAbsolute = 1
202pp_data->cap[3]->IsRange = 0
203pp_data->cap[3]->IsAlias = 0
204pp_data->cap[3]->IsStringRange = 0
205pp_data->cap[3]->IsDesignatorRange = 0
206pp_data->cap[3]->Reserved1 = 0x000000
207pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
208pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
209pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
210pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
211pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
212pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
213pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
214pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
215pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
216pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
217pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
218pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
219pp_data->cap[3]->NotRange.Usage = 0x0039
220pp_data->cap[3]->NotRange.Reserved1 = 0x0039
221pp_data->cap[3]->NotRange.StringIndex = 0
222pp_data->cap[3]->NotRange.Reserved2 = 0
223pp_data->cap[3]->NotRange.DesignatorIndex = 0
224pp_data->cap[3]->NotRange.Reserved3 = 0
225pp_data->cap[3]->NotRange.DataIndex = 3
226pp_data->cap[3]->NotRange.Reserved4 = 3
227pp_data->cap[3]->NotButton.HasNull = 1
228pp_data->cap[3]->NotButton.Reserved4 = 0x000000
229pp_data->cap[3]->NotButton.LogicalMin = 0
230pp_data->cap[3]->NotButton.LogicalMax = 7
231pp_data->cap[3]->NotButton.PhysicalMin = 0
232pp_data->cap[3]->NotButton.PhysicalMax = 315
233pp_data->cap[3]->Units = 20
234pp_data->cap[3]->UnitsExp = 0
235
236pp_data->cap[4]->UsagePage = 0x0001
237pp_data->cap[4]->ReportID = 0x00
238pp_data->cap[4]->BitPosition = 0
239pp_data->cap[4]->BitSize = 8
240pp_data->cap[4]->ReportCount = 1
241pp_data->cap[4]->BytePosition = 0x0004
242pp_data->cap[4]->BitCount = 8
243pp_data->cap[4]->BitField = 0x02
244pp_data->cap[4]->NextBytePosition = 0x0005
245pp_data->cap[4]->LinkCollection = 0x0002
246pp_data->cap[4]->LinkUsagePage = 0x0001
247pp_data->cap[4]->LinkUsage = 0x0001
248pp_data->cap[4]->IsMultipleItemsForArray = 0
249pp_data->cap[4]->IsButtonCap = 0
250pp_data->cap[4]->IsPadding = 0
251pp_data->cap[4]->IsAbsolute = 1
252pp_data->cap[4]->IsRange = 0
253pp_data->cap[4]->IsAlias = 0
254pp_data->cap[4]->IsStringRange = 0
255pp_data->cap[4]->IsDesignatorRange = 0
256pp_data->cap[4]->Reserved1 = 0x000000
257pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
258pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
259pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
260pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
261pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
262pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
263pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
264pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
265pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
266pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
267pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
268pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
269pp_data->cap[4]->NotRange.Usage = 0x0035
270pp_data->cap[4]->NotRange.Reserved1 = 0x0035
271pp_data->cap[4]->NotRange.StringIndex = 0
272pp_data->cap[4]->NotRange.Reserved2 = 0
273pp_data->cap[4]->NotRange.DesignatorIndex = 0
274pp_data->cap[4]->NotRange.Reserved3 = 0
275pp_data->cap[4]->NotRange.DataIndex = 4
276pp_data->cap[4]->NotRange.Reserved4 = 4
277pp_data->cap[4]->NotButton.HasNull = 0
278pp_data->cap[4]->NotButton.Reserved4 = 0x000000
279pp_data->cap[4]->NotButton.LogicalMin = 0
280pp_data->cap[4]->NotButton.LogicalMax = 255
281pp_data->cap[4]->NotButton.PhysicalMin = 0
282pp_data->cap[4]->NotButton.PhysicalMax = 255
283pp_data->cap[4]->Units = 20
284pp_data->cap[4]->UnitsExp = 0
285
286pp_data->cap[5]->UsagePage = 0x0009
287pp_data->cap[5]->ReportID = 0x00
288pp_data->cap[5]->BitPosition = 0
289pp_data->cap[5]->BitSize = 1
290pp_data->cap[5]->ReportCount = 7
291pp_data->cap[5]->BytePosition = 0x0005
292pp_data->cap[5]->BitCount = 7
293pp_data->cap[5]->BitField = 0x02
294pp_data->cap[5]->NextBytePosition = 0x0006
295pp_data->cap[5]->LinkCollection = 0x0001
296pp_data->cap[5]->LinkUsagePage = 0x0001
297pp_data->cap[5]->LinkUsage = 0x0000
298pp_data->cap[5]->IsMultipleItemsForArray = 0
299pp_data->cap[5]->IsButtonCap = 1
300pp_data->cap[5]->IsPadding = 0
301pp_data->cap[5]->IsAbsolute = 1
302pp_data->cap[5]->IsRange = 1
303pp_data->cap[5]->IsAlias = 0
304pp_data->cap[5]->IsStringRange = 0
305pp_data->cap[5]->IsDesignatorRange = 0
306pp_data->cap[5]->Reserved1 = 0x000000
307pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
308pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
309pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
310pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
311pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
312pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
313pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
314pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
315pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
316pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
317pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
318pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
319pp_data->cap[5]->Range.UsageMin = 0x0001
320pp_data->cap[5]->Range.UsageMax = 0x0007
321pp_data->cap[5]->Range.StringMin = 0
322pp_data->cap[5]->Range.StringMax = 0
323pp_data->cap[5]->Range.DesignatorMin = 0
324pp_data->cap[5]->Range.DesignatorMax = 0
325pp_data->cap[5]->Range.DataIndexMin = 5
326pp_data->cap[5]->Range.DataIndexMax = 11
327pp_data->cap[5]->Button.LogicalMin = 0
328pp_data->cap[5]->Button.LogicalMax = 0
329pp_data->cap[5]->Units = 0
330pp_data->cap[5]->UnitsExp = 0
331
332pp_data->cap[6]->UsagePage = 0x0001
333pp_data->cap[6]->ReportID = 0x00
334pp_data->cap[6]->BitPosition = 0
335pp_data->cap[6]->BitSize = 8
336pp_data->cap[6]->ReportCount = 1
337pp_data->cap[6]->BytePosition = 0x0006
338pp_data->cap[6]->BitCount = 8
339pp_data->cap[6]->BitField = 0x02
340pp_data->cap[6]->NextBytePosition = 0x0007
341pp_data->cap[6]->LinkCollection = 0x0001
342pp_data->cap[6]->LinkUsagePage = 0x0001
343pp_data->cap[6]->LinkUsage = 0x0000
344pp_data->cap[6]->IsMultipleItemsForArray = 0
345pp_data->cap[6]->IsButtonCap = 0
346pp_data->cap[6]->IsPadding = 0
347pp_data->cap[6]->IsAbsolute = 1
348pp_data->cap[6]->IsRange = 0
349pp_data->cap[6]->IsAlias = 0
350pp_data->cap[6]->IsStringRange = 0
351pp_data->cap[6]->IsDesignatorRange = 0
352pp_data->cap[6]->Reserved1 = 0x000000
353pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
354pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
355pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
356pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
357pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
358pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
359pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
360pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
361pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
362pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
363pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
364pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
365pp_data->cap[6]->NotRange.Usage = 0x0036
366pp_data->cap[6]->NotRange.Reserved1 = 0x0036
367pp_data->cap[6]->NotRange.StringIndex = 0
368pp_data->cap[6]->NotRange.Reserved2 = 0
369pp_data->cap[6]->NotRange.DesignatorIndex = 0
370pp_data->cap[6]->NotRange.Reserved3 = 0
371pp_data->cap[6]->NotRange.DataIndex = 12
372pp_data->cap[6]->NotRange.Reserved4 = 12
373pp_data->cap[6]->NotButton.HasNull = 0
374pp_data->cap[6]->NotButton.Reserved4 = 0x000000
375pp_data->cap[6]->NotButton.LogicalMin = 0
376pp_data->cap[6]->NotButton.LogicalMax = 255
377pp_data->cap[6]->NotButton.PhysicalMin = 0
378pp_data->cap[6]->NotButton.PhysicalMax = 255
379pp_data->cap[6]->Units = 0
380pp_data->cap[6]->UnitsExp = 0
381
382pp_data->cap[7]->UsagePage = 0xFF00
383pp_data->cap[7]->ReportID = 0x00
384pp_data->cap[7]->BitPosition = 0
385pp_data->cap[7]->BitSize = 8
386pp_data->cap[7]->ReportCount = 1
387pp_data->cap[7]->BytePosition = 0x0007
388pp_data->cap[7]->BitCount = 8
389pp_data->cap[7]->BitField = 0x02
390pp_data->cap[7]->NextBytePosition = 0x0008
391pp_data->cap[7]->LinkCollection = 0x0001
392pp_data->cap[7]->LinkUsagePage = 0x0001
393pp_data->cap[7]->LinkUsage = 0x0000
394pp_data->cap[7]->IsMultipleItemsForArray = 0
395pp_data->cap[7]->IsButtonCap = 0
396pp_data->cap[7]->IsPadding = 0
397pp_data->cap[7]->IsAbsolute = 1
398pp_data->cap[7]->IsRange = 0
399pp_data->cap[7]->IsAlias = 0
400pp_data->cap[7]->IsStringRange = 0
401pp_data->cap[7]->IsDesignatorRange = 0
402pp_data->cap[7]->Reserved1 = 0x000000
403pp_data->cap[7]->pp_cap->UnknownTokens[0].Token = 0x00
404pp_data->cap[7]->pp_cap->UnknownTokens[0].Reserved = 0x000000
405pp_data->cap[7]->pp_cap->UnknownTokens[0].BitField = 0x00000000
406pp_data->cap[7]->pp_cap->UnknownTokens[1].Token = 0x00
407pp_data->cap[7]->pp_cap->UnknownTokens[1].Reserved = 0x000000
408pp_data->cap[7]->pp_cap->UnknownTokens[1].BitField = 0x00000000
409pp_data->cap[7]->pp_cap->UnknownTokens[2].Token = 0x00
410pp_data->cap[7]->pp_cap->UnknownTokens[2].Reserved = 0x000000
411pp_data->cap[7]->pp_cap->UnknownTokens[2].BitField = 0x00000000
412pp_data->cap[7]->pp_cap->UnknownTokens[3].Token = 0x00
413pp_data->cap[7]->pp_cap->UnknownTokens[3].Reserved = 0x000000
414pp_data->cap[7]->pp_cap->UnknownTokens[3].BitField = 0x00000000
415pp_data->cap[7]->NotRange.Usage = 0x0001
416pp_data->cap[7]->NotRange.Reserved1 = 0x0001
417pp_data->cap[7]->NotRange.StringIndex = 0
418pp_data->cap[7]->NotRange.Reserved2 = 0
419pp_data->cap[7]->NotRange.DesignatorIndex = 0
420pp_data->cap[7]->NotRange.Reserved3 = 0
421pp_data->cap[7]->NotRange.DataIndex = 13
422pp_data->cap[7]->NotRange.Reserved4 = 13
423pp_data->cap[7]->NotButton.HasNull = 0
424pp_data->cap[7]->NotButton.Reserved4 = 0x000000
425pp_data->cap[7]->NotButton.LogicalMin = 0
426pp_data->cap[7]->NotButton.LogicalMax = 255
427pp_data->cap[7]->NotButton.PhysicalMin = 0
428pp_data->cap[7]->NotButton.PhysicalMax = 255
429pp_data->cap[7]->Units = 0
430pp_data->cap[7]->UnitsExp = 0
431
432# Output hid_pp_cap struct:
433pp_data->cap[8]->UsagePage = 0xFF00
434pp_data->cap[8]->ReportID = 0x00
435pp_data->cap[8]->BitPosition = 0
436pp_data->cap[8]->BitSize = 8
437pp_data->cap[8]->ReportCount = 8
438pp_data->cap[8]->BytePosition = 0x0001
439pp_data->cap[8]->BitCount = 64
440pp_data->cap[8]->BitField = 0x02
441pp_data->cap[8]->NextBytePosition = 0x0009
442pp_data->cap[8]->LinkCollection = 0x0003
443pp_data->cap[8]->LinkUsagePage = 0xFF00
444pp_data->cap[8]->LinkUsage = 0x0000
445pp_data->cap[8]->IsMultipleItemsForArray = 0
446pp_data->cap[8]->IsButtonCap = 0
447pp_data->cap[8]->IsPadding = 0
448pp_data->cap[8]->IsAbsolute = 1
449pp_data->cap[8]->IsRange = 0
450pp_data->cap[8]->IsAlias = 0
451pp_data->cap[8]->IsStringRange = 0
452pp_data->cap[8]->IsDesignatorRange = 0
453pp_data->cap[8]->Reserved1 = 0x000000
454pp_data->cap[8]->pp_cap->UnknownTokens[0].Token = 0x00
455pp_data->cap[8]->pp_cap->UnknownTokens[0].Reserved = 0x000000
456pp_data->cap[8]->pp_cap->UnknownTokens[0].BitField = 0x00000000
457pp_data->cap[8]->pp_cap->UnknownTokens[1].Token = 0x00
458pp_data->cap[8]->pp_cap->UnknownTokens[1].Reserved = 0x000000
459pp_data->cap[8]->pp_cap->UnknownTokens[1].BitField = 0x00000000
460pp_data->cap[8]->pp_cap->UnknownTokens[2].Token = 0x00
461pp_data->cap[8]->pp_cap->UnknownTokens[2].Reserved = 0x000000
462pp_data->cap[8]->pp_cap->UnknownTokens[2].BitField = 0x00000000
463pp_data->cap[8]->pp_cap->UnknownTokens[3].Token = 0x00
464pp_data->cap[8]->pp_cap->UnknownTokens[3].Reserved = 0x000000
465pp_data->cap[8]->pp_cap->UnknownTokens[3].BitField = 0x00000000
466pp_data->cap[8]->NotRange.Usage = 0x0002
467pp_data->cap[8]->NotRange.Reserved1 = 0x0002
468pp_data->cap[8]->NotRange.StringIndex = 0
469pp_data->cap[8]->NotRange.Reserved2 = 0
470pp_data->cap[8]->NotRange.DesignatorIndex = 0
471pp_data->cap[8]->NotRange.Reserved3 = 0
472pp_data->cap[8]->NotRange.DataIndex = 0
473pp_data->cap[8]->NotRange.Reserved4 = 0
474pp_data->cap[8]->NotButton.HasNull = 0
475pp_data->cap[8]->NotButton.Reserved4 = 0x000000
476pp_data->cap[8]->NotButton.LogicalMin = 0
477pp_data->cap[8]->NotButton.LogicalMax = 255
478pp_data->cap[8]->NotButton.PhysicalMin = 0
479pp_data->cap[8]->NotButton.PhysicalMax = 255
480pp_data->cap[8]->Units = 0
481pp_data->cap[8]->UnitsExp = 0
482
483# Feature hid_pp_cap struct:
484# Link Collections:
485pp_data->LinkCollectionArray[0]->LinkUsage = 0x0004
486pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
487pp_data->LinkCollectionArray[0]->Parent = 0
488pp_data->LinkCollectionArray[0]->NumberOfChildren = 2
489pp_data->LinkCollectionArray[0]->NextSibling = 0
490pp_data->LinkCollectionArray[0]->FirstChild = 3
491pp_data->LinkCollectionArray[0]->CollectionType = 1
492pp_data->LinkCollectionArray[0]->IsAlias = 0
493pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
494pp_data->LinkCollectionArray[1]->LinkUsage = 0x0000
495pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
496pp_data->LinkCollectionArray[1]->Parent = 0
497pp_data->LinkCollectionArray[1]->NumberOfChildren = 1
498pp_data->LinkCollectionArray[1]->NextSibling = 0
499pp_data->LinkCollectionArray[1]->FirstChild = 2
500pp_data->LinkCollectionArray[1]->CollectionType = 2
501pp_data->LinkCollectionArray[1]->IsAlias = 0
502pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
503pp_data->LinkCollectionArray[2]->LinkUsage = 0x0001
504pp_data->LinkCollectionArray[2]->LinkUsagePage = 0x0001
505pp_data->LinkCollectionArray[2]->Parent = 1
506pp_data->LinkCollectionArray[2]->NumberOfChildren = 0
507pp_data->LinkCollectionArray[2]->NextSibling = 0
508pp_data->LinkCollectionArray[2]->FirstChild = 0
509pp_data->LinkCollectionArray[2]->CollectionType = 0
510pp_data->LinkCollectionArray[2]->IsAlias = 0
511pp_data->LinkCollectionArray[2]->Reserved = 0x00000000
512pp_data->LinkCollectionArray[3]->LinkUsage = 0x0000
513pp_data->LinkCollectionArray[3]->LinkUsagePage = 0xFF00
514pp_data->LinkCollectionArray[3]->Parent = 0
515pp_data->LinkCollectionArray[3]->NumberOfChildren = 0
516pp_data->LinkCollectionArray[3]->NextSibling = 1
517pp_data->LinkCollectionArray[3]->FirstChild = 0
518pp_data->LinkCollectionArray[3]->CollectionType = 2
519pp_data->LinkCollectionArray[3]->IsAlias = 0
520pp_data->LinkCollectionArray[3]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_expected.rpt_desc
new file mode 100644
index 0000000..fca719a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_expected.rpt_desc
@@ -0,0 +1,18 @@
10x05, 0x01, 0x09, 0x04, 0xA1, 0x01, 0x09, 0x00, 0xA1, 0x02,
20x09, 0x01, 0xA1, 0x00, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00,
30x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75, 0x08,
40x95, 0x02, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01, 0x15,
50x00, 0x25, 0x0F, 0x75, 0x04, 0x95, 0x01, 0x81, 0x02, 0x05,
60x01, 0x09, 0x39, 0x15, 0x00, 0x25, 0x07, 0x35, 0x00, 0x46,
70x3B, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42,
80x09, 0x35, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46,
90xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x02, 0xC0, 0x05,
100x09, 0x19, 0x01, 0x29, 0x07, 0x15, 0x00, 0x25, 0x01, 0x75,
110x01, 0x95, 0x07, 0x45, 0x00, 0x65, 0x00, 0x81, 0x02, 0x75,
120x01, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x36, 0x15,
130x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75,
140x08, 0x95, 0x01, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01,
150x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81,
160x02, 0xC0, 0x09, 0x00, 0xA1, 0x02, 0x09, 0x02, 0x15, 0x00,
170x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x08, 0x91, 0x02, 0xC0,
180xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_real.rpt_desc
new file mode 100644
index 0000000..fca719a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C283_0004_0001_real.rpt_desc
@@ -0,0 +1,18 @@
10x05, 0x01, 0x09, 0x04, 0xA1, 0x01, 0x09, 0x00, 0xA1, 0x02,
20x09, 0x01, 0xA1, 0x00, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00,
30x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75, 0x08,
40x95, 0x02, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01, 0x15,
50x00, 0x25, 0x0F, 0x75, 0x04, 0x95, 0x01, 0x81, 0x02, 0x05,
60x01, 0x09, 0x39, 0x15, 0x00, 0x25, 0x07, 0x35, 0x00, 0x46,
70x3B, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42,
80x09, 0x35, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46,
90xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x02, 0xC0, 0x05,
100x09, 0x19, 0x01, 0x29, 0x07, 0x15, 0x00, 0x25, 0x01, 0x75,
110x01, 0x95, 0x07, 0x45, 0x00, 0x65, 0x00, 0x81, 0x02, 0x75,
120x01, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x36, 0x15,
130x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75,
140x08, 0x95, 0x01, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01,
150x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81,
160x02, 0xC0, 0x09, 0x00, 0xA1, 0x02, 0x09, 0x02, 0x15, 0x00,
170x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x08, 0x91, 0x02, 0xC0,
180xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C.pp_data
new file mode 100644
index 0000000..7f6b369
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C.pp_data
@@ -0,0 +1,93 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC52F
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2200
7dev->interface_number = 1
8dev->usage = 0x0001
9dev->usage_page = 0x000C
10dev->path = "\\?\hid#vid_046d&pid_c52f&mi_01&col01#8&28ca146b&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0x000C
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 5
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 1
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 1
29pp_data->caps_info[2]->LastCap = 1
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0068
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x000C
37pp_data->cap[0]->ReportID = 0x03
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 16
40pp_data->cap[0]->ReportCount = 2
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 32
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0005
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x000C
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x0001
70pp_data->cap[0]->Range.UsageMax = 0x028C
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 651
77pp_data->cap[0]->Button.LogicalMin = 1
78pp_data->cap[0]->Button.LogicalMax = 652
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83# Feature hid_pp_cap struct:
84# Link Collections:
85pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
86pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
87pp_data->LinkCollectionArray[0]->Parent = 0
88pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
89pp_data->LinkCollectionArray[0]->NextSibling = 0
90pp_data->LinkCollectionArray[0]->FirstChild = 0
91pp_data->LinkCollectionArray[0]->CollectionType = 1
92pp_data->LinkCollectionArray[0]->IsAlias = 0
93pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_expected.rpt_desc
new file mode 100644
index 0000000..85953ae
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_expected.rpt_desc
@@ -0,0 +1,3 @@
10x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x03, 0x19, 0x01,
20x2A, 0x8C, 0x02, 0x15, 0x01, 0x26, 0x8C, 0x02, 0x75, 0x10,
30x95, 0x02, 0x81, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_real.rpt_desc
new file mode 100644
index 0000000..280e58f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_000C_real.rpt_desc
@@ -0,0 +1,12 @@
1Usage Page (Consumer Devices) 05 0C
2Usage (Consumer Control) 09 01
3Collection (Application) A1 01
4 Report ID (3) 85 03
5 Report Size (16) 75 10
6 Report Count (2) 95 02
7 Logical Minimum (1) 15 01
8 Logical Maximum (652) 26 8C 02
9 Usage Minimum (Consumer Control) 19 01
10 Usage Maximum (AC Send) 2A 8C 02
11 Input (Data,Ary,Abs) 81 00
12End Collection C0
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00.pp_data
new file mode 100644
index 0000000..5e8ece1
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00.pp_data
@@ -0,0 +1,139 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC52F
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2200
7dev->interface_number = 1
8dev->usage = 0x0001
9dev->usage_page = 0xFF00
10dev->path = "\\?\hid#vid_046d&pid_c52f&mi_01&col02#8&28ca146b&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0xFF00
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 7
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 2
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 7
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 2
29pp_data->caps_info[2]->LastCap = 2
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x00D0
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFF00
37pp_data->cap[0]->ReportID = 0x10
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 6
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 48
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0007
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0xFF00
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0001
70pp_data->cap[0]->NotRange.Reserved1 = 0x0001
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 255
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83pp_data->cap[1]->UsagePage = 0xFF00
84pp_data->cap[1]->ReportID = 0x10
85pp_data->cap[1]->BitPosition = 0
86pp_data->cap[1]->BitSize = 8
87pp_data->cap[1]->ReportCount = 6
88pp_data->cap[1]->BytePosition = 0x0001
89pp_data->cap[1]->BitCount = 48
90pp_data->cap[1]->BitField = 0x00
91pp_data->cap[1]->NextBytePosition = 0x0007
92pp_data->cap[1]->LinkCollection = 0x0000
93pp_data->cap[1]->LinkUsagePage = 0xFF00
94pp_data->cap[1]->LinkUsage = 0x0001
95pp_data->cap[1]->IsMultipleItemsForArray = 0
96pp_data->cap[1]->IsButtonCap = 1
97pp_data->cap[1]->IsPadding = 0
98pp_data->cap[1]->IsAbsolute = 1
99pp_data->cap[1]->IsRange = 0
100pp_data->cap[1]->IsAlias = 0
101pp_data->cap[1]->IsStringRange = 0
102pp_data->cap[1]->IsDesignatorRange = 0
103pp_data->cap[1]->Reserved1 = 0x000000
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
105pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
106pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
116pp_data->cap[1]->NotRange.Usage = 0x0001
117pp_data->cap[1]->NotRange.Reserved1 = 0x0001
118pp_data->cap[1]->NotRange.StringIndex = 0
119pp_data->cap[1]->NotRange.Reserved2 = 0
120pp_data->cap[1]->NotRange.DesignatorIndex = 0
121pp_data->cap[1]->NotRange.Reserved3 = 0
122pp_data->cap[1]->NotRange.DataIndex = 0
123pp_data->cap[1]->NotRange.Reserved4 = 0
124pp_data->cap[1]->Button.LogicalMin = 0
125pp_data->cap[1]->Button.LogicalMax = 255
126pp_data->cap[1]->Units = 0
127pp_data->cap[1]->UnitsExp = 0
128
129# Feature hid_pp_cap struct:
130# Link Collections:
131pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
132pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
133pp_data->LinkCollectionArray[0]->Parent = 0
134pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
135pp_data->LinkCollectionArray[0]->NextSibling = 0
136pp_data->LinkCollectionArray[0]->FirstChild = 0
137pp_data->LinkCollectionArray[0]->CollectionType = 1
138pp_data->LinkCollectionArray[0]->IsAlias = 0
139pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_expected.rpt_desc
new file mode 100644
index 0000000..812bd2a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_expected.rpt_desc
@@ -0,0 +1,4 @@
10x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x09,
20x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x06,
30x81, 0x00, 0x09, 0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
40x08, 0x95, 0x06, 0x91, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_real.rpt_desc
new file mode 100644
index 0000000..0db6898
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0001_FF00_real.rpt_desc
@@ -0,0 +1,13 @@
1Usage Page (Vendor-Defined 1) 06 00 FF
2Usage (Vendor-Defined 1) 09 01
3Collection (Application) A1 01
4 Report ID (16) 85 10
5 Report Size (8) 75 08
6 Report Count (6) 95 06
7 Logical Minimum (0) 15 00
8 Logical Maximum (255) 26 FF 00
9 Usage (Vendor-Defined 1) 09 01
10 Input (Data,Ary,Abs) 81 00
11 Usage (Vendor-Defined 1) 09 01
12 Output (Data,Ary,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 00
13End Collection C0
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001.pp_data
new file mode 100644
index 0000000..d90e666
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001.pp_data
@@ -0,0 +1,302 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC52F
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2200
7dev->interface_number = 0
8dev->usage = 0x0002
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#vid_046d&pid_c52f&mi_00#8&1599f82d&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0002
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 5
20pp_data->caps_info[0]->NumberOfCaps = 5
21pp_data->caps_info[0]->ReportByteLength = 9
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 5
24pp_data->caps_info[1]->LastCap = 5
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 5
29pp_data->caps_info[2]->LastCap = 5
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0208
34pp_data->NumberLinkCollectionNodes = 2
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0009
37pp_data->cap[0]->ReportID = 0x00
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 16
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 16
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0003
45pp_data->cap[0]->LinkCollection = 0x0001
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x0001
70pp_data->cap[0]->Range.UsageMax = 0x0010
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 15
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x0001
83pp_data->cap[1]->ReportID = 0x00
84pp_data->cap[1]->BitPosition = 0
85pp_data->cap[1]->BitSize = 16
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0005
88pp_data->cap[1]->BitCount = 16
89pp_data->cap[1]->BitField = 0x06
90pp_data->cap[1]->NextBytePosition = 0x0007
91pp_data->cap[1]->LinkCollection = 0x0001
92pp_data->cap[1]->LinkUsagePage = 0x0001
93pp_data->cap[1]->LinkUsage = 0x0001
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 0
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 0
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x0031
116pp_data->cap[1]->NotRange.Reserved1 = 0x0031
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 16
122pp_data->cap[1]->NotRange.Reserved4 = 16
123pp_data->cap[1]->NotButton.HasNull = 0
124pp_data->cap[1]->NotButton.Reserved4 = 0x000000
125pp_data->cap[1]->NotButton.LogicalMin = -32767
126pp_data->cap[1]->NotButton.LogicalMax = 32767
127pp_data->cap[1]->NotButton.PhysicalMin = 0
128pp_data->cap[1]->NotButton.PhysicalMax = 0
129pp_data->cap[1]->Units = 0
130pp_data->cap[1]->UnitsExp = 0
131
132pp_data->cap[2]->UsagePage = 0x0001
133pp_data->cap[2]->ReportID = 0x00
134pp_data->cap[2]->BitPosition = 0
135pp_data->cap[2]->BitSize = 16
136pp_data->cap[2]->ReportCount = 1
137pp_data->cap[2]->BytePosition = 0x0003
138pp_data->cap[2]->BitCount = 16
139pp_data->cap[2]->BitField = 0x06
140pp_data->cap[2]->NextBytePosition = 0x0005
141pp_data->cap[2]->LinkCollection = 0x0001
142pp_data->cap[2]->LinkUsagePage = 0x0001
143pp_data->cap[2]->LinkUsage = 0x0001
144pp_data->cap[2]->IsMultipleItemsForArray = 0
145pp_data->cap[2]->IsButtonCap = 0
146pp_data->cap[2]->IsPadding = 0
147pp_data->cap[2]->IsAbsolute = 0
148pp_data->cap[2]->IsRange = 0
149pp_data->cap[2]->IsAlias = 0
150pp_data->cap[2]->IsStringRange = 0
151pp_data->cap[2]->IsDesignatorRange = 0
152pp_data->cap[2]->Reserved1 = 0x000000
153pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
154pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
155pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
156pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
157pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
158pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
159pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
160pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
161pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
162pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
163pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
164pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
165pp_data->cap[2]->NotRange.Usage = 0x0030
166pp_data->cap[2]->NotRange.Reserved1 = 0x0030
167pp_data->cap[2]->NotRange.StringIndex = 0
168pp_data->cap[2]->NotRange.Reserved2 = 0
169pp_data->cap[2]->NotRange.DesignatorIndex = 0
170pp_data->cap[2]->NotRange.Reserved3 = 0
171pp_data->cap[2]->NotRange.DataIndex = 17
172pp_data->cap[2]->NotRange.Reserved4 = 17
173pp_data->cap[2]->NotButton.HasNull = 0
174pp_data->cap[2]->NotButton.Reserved4 = 0x000000
175pp_data->cap[2]->NotButton.LogicalMin = -32767
176pp_data->cap[2]->NotButton.LogicalMax = 32767
177pp_data->cap[2]->NotButton.PhysicalMin = 0
178pp_data->cap[2]->NotButton.PhysicalMax = 0
179pp_data->cap[2]->Units = 0
180pp_data->cap[2]->UnitsExp = 0
181
182pp_data->cap[3]->UsagePage = 0x0001
183pp_data->cap[3]->ReportID = 0x00
184pp_data->cap[3]->BitPosition = 0
185pp_data->cap[3]->BitSize = 8
186pp_data->cap[3]->ReportCount = 1
187pp_data->cap[3]->BytePosition = 0x0007
188pp_data->cap[3]->BitCount = 8
189pp_data->cap[3]->BitField = 0x06
190pp_data->cap[3]->NextBytePosition = 0x0008
191pp_data->cap[3]->LinkCollection = 0x0001
192pp_data->cap[3]->LinkUsagePage = 0x0001
193pp_data->cap[3]->LinkUsage = 0x0001
194pp_data->cap[3]->IsMultipleItemsForArray = 0
195pp_data->cap[3]->IsButtonCap = 0
196pp_data->cap[3]->IsPadding = 0
197pp_data->cap[3]->IsAbsolute = 0
198pp_data->cap[3]->IsRange = 0
199pp_data->cap[3]->IsAlias = 0
200pp_data->cap[3]->IsStringRange = 0
201pp_data->cap[3]->IsDesignatorRange = 0
202pp_data->cap[3]->Reserved1 = 0x000000
203pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
204pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
205pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
206pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
207pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
208pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
209pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
210pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
211pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
212pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
213pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
214pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
215pp_data->cap[3]->NotRange.Usage = 0x0038
216pp_data->cap[3]->NotRange.Reserved1 = 0x0038
217pp_data->cap[3]->NotRange.StringIndex = 0
218pp_data->cap[3]->NotRange.Reserved2 = 0
219pp_data->cap[3]->NotRange.DesignatorIndex = 0
220pp_data->cap[3]->NotRange.Reserved3 = 0
221pp_data->cap[3]->NotRange.DataIndex = 18
222pp_data->cap[3]->NotRange.Reserved4 = 18
223pp_data->cap[3]->NotButton.HasNull = 0
224pp_data->cap[3]->NotButton.Reserved4 = 0x000000
225pp_data->cap[3]->NotButton.LogicalMin = -127
226pp_data->cap[3]->NotButton.LogicalMax = 127
227pp_data->cap[3]->NotButton.PhysicalMin = 0
228pp_data->cap[3]->NotButton.PhysicalMax = 0
229pp_data->cap[3]->Units = 0
230pp_data->cap[3]->UnitsExp = 0
231
232pp_data->cap[4]->UsagePage = 0x000C
233pp_data->cap[4]->ReportID = 0x00
234pp_data->cap[4]->BitPosition = 0
235pp_data->cap[4]->BitSize = 8
236pp_data->cap[4]->ReportCount = 1
237pp_data->cap[4]->BytePosition = 0x0008
238pp_data->cap[4]->BitCount = 8
239pp_data->cap[4]->BitField = 0x06
240pp_data->cap[4]->NextBytePosition = 0x0009
241pp_data->cap[4]->LinkCollection = 0x0001
242pp_data->cap[4]->LinkUsagePage = 0x0001
243pp_data->cap[4]->LinkUsage = 0x0001
244pp_data->cap[4]->IsMultipleItemsForArray = 0
245pp_data->cap[4]->IsButtonCap = 0
246pp_data->cap[4]->IsPadding = 0
247pp_data->cap[4]->IsAbsolute = 0
248pp_data->cap[4]->IsRange = 0
249pp_data->cap[4]->IsAlias = 0
250pp_data->cap[4]->IsStringRange = 0
251pp_data->cap[4]->IsDesignatorRange = 0
252pp_data->cap[4]->Reserved1 = 0x000000
253pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
254pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
255pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
256pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
257pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
258pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
259pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
260pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
261pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
262pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
263pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
264pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
265pp_data->cap[4]->NotRange.Usage = 0x0238
266pp_data->cap[4]->NotRange.Reserved1 = 0x0238
267pp_data->cap[4]->NotRange.StringIndex = 0
268pp_data->cap[4]->NotRange.Reserved2 = 0
269pp_data->cap[4]->NotRange.DesignatorIndex = 0
270pp_data->cap[4]->NotRange.Reserved3 = 0
271pp_data->cap[4]->NotRange.DataIndex = 19
272pp_data->cap[4]->NotRange.Reserved4 = 19
273pp_data->cap[4]->NotButton.HasNull = 0
274pp_data->cap[4]->NotButton.Reserved4 = 0x000000
275pp_data->cap[4]->NotButton.LogicalMin = -127
276pp_data->cap[4]->NotButton.LogicalMax = 127
277pp_data->cap[4]->NotButton.PhysicalMin = 0
278pp_data->cap[4]->NotButton.PhysicalMax = 0
279pp_data->cap[4]->Units = 0
280pp_data->cap[4]->UnitsExp = 0
281
282# Output hid_pp_cap struct:
283# Feature hid_pp_cap struct:
284# Link Collections:
285pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
286pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
287pp_data->LinkCollectionArray[0]->Parent = 0
288pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
289pp_data->LinkCollectionArray[0]->NextSibling = 0
290pp_data->LinkCollectionArray[0]->FirstChild = 1
291pp_data->LinkCollectionArray[0]->CollectionType = 1
292pp_data->LinkCollectionArray[0]->IsAlias = 0
293pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
294pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
295pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
296pp_data->LinkCollectionArray[1]->Parent = 0
297pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
298pp_data->LinkCollectionArray[1]->NextSibling = 0
299pp_data->LinkCollectionArray[1]->FirstChild = 0
300pp_data->LinkCollectionArray[1]->CollectionType = 0
301pp_data->LinkCollectionArray[1]->IsAlias = 0
302pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_expected.rpt_desc
new file mode 100644
index 0000000..128c411
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_expected.rpt_desc
@@ -0,0 +1,8 @@
10x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
20x05, 0x09, 0x19, 0x01, 0x29, 0x10, 0x15, 0x00, 0x25, 0x01,
30x75, 0x01, 0x95, 0x10, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30,
40x09, 0x31, 0x16, 0x01, 0x80, 0x26, 0xFF, 0x7F, 0x75, 0x10,
50x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7F,
60x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0x05, 0x0C, 0x0A, 0x38,
70x02, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81,
80x06, 0xC0, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_real.rpt_desc
new file mode 100644
index 0000000..9c0521d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_0001_real.rpt_desc
@@ -0,0 +1,33 @@
1Usage Page (Generic Desktop) 05 01
2Usage (Mouse) 09 02
3Collection (Application) A1 01
4 Usage (Pointer) 09 01
5 Collection (Physical) A1 00
6 Usage Page (Button) 05 09
7 Usage Minimum (Button 1) 19 01
8 Usage Maximum (Button 16) 29 10
9 Logical Minimum (0) 15 00
10 Logical Maximum (1) 25 01
11 Report Count (16) 95 10
12 Report Size (1) 75 01
13 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
14 Usage Page (Generic Desktop) 05 01
15 Logical Minimum (-32767) 16 01 80
16 Logical Maximum (32767) 26 FF 7F
17 Report Size (16) 75 10
18 Report Count (2) 95 02
19 Usage (X) 09 30
20 Usage (Y) 09 31
21 Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
22 Logical Minimum (-127) 15 81
23 Logical Maximum (127) 25 7F
24 Report Size (8) 75 08
25 Report Count (1) 95 01
26 Usage (Wheel) 09 38
27 Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
28 Usage Page (Consumer Devices) 05 0C
29 Usage (AC Pan) 0A 38 02
30 Report Count (1) 95 01
31 Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
32 End Collection C0
33End Collection C0
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00.pp_data
new file mode 100644
index 0000000..09a3689
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00.pp_data
@@ -0,0 +1,139 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC52F
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2200
7dev->interface_number = 1
8dev->usage = 0x0002
9dev->usage_page = 0xFF00
10dev->path = "\\?\hid#vid_046d&pid_c52f&mi_01&col03#8&28ca146b&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0002
15pp_data->UsagePage = 0xFF00
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 20
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 2
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 20
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 2
29pp_data->caps_info[2]->LastCap = 2
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x00D0
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFF00
37pp_data->cap[0]->ReportID = 0x11
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 19
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 152
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0014
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0xFF00
47pp_data->cap[0]->LinkUsage = 0x0002
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0002
70pp_data->cap[0]->NotRange.Reserved1 = 0x0002
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 255
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83pp_data->cap[1]->UsagePage = 0xFF00
84pp_data->cap[1]->ReportID = 0x11
85pp_data->cap[1]->BitPosition = 0
86pp_data->cap[1]->BitSize = 8
87pp_data->cap[1]->ReportCount = 19
88pp_data->cap[1]->BytePosition = 0x0001
89pp_data->cap[1]->BitCount = 152
90pp_data->cap[1]->BitField = 0x00
91pp_data->cap[1]->NextBytePosition = 0x0014
92pp_data->cap[1]->LinkCollection = 0x0000
93pp_data->cap[1]->LinkUsagePage = 0xFF00
94pp_data->cap[1]->LinkUsage = 0x0002
95pp_data->cap[1]->IsMultipleItemsForArray = 0
96pp_data->cap[1]->IsButtonCap = 1
97pp_data->cap[1]->IsPadding = 0
98pp_data->cap[1]->IsAbsolute = 1
99pp_data->cap[1]->IsRange = 0
100pp_data->cap[1]->IsAlias = 0
101pp_data->cap[1]->IsStringRange = 0
102pp_data->cap[1]->IsDesignatorRange = 0
103pp_data->cap[1]->Reserved1 = 0x000000
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
105pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
106pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
116pp_data->cap[1]->NotRange.Usage = 0x0002
117pp_data->cap[1]->NotRange.Reserved1 = 0x0002
118pp_data->cap[1]->NotRange.StringIndex = 0
119pp_data->cap[1]->NotRange.Reserved2 = 0
120pp_data->cap[1]->NotRange.DesignatorIndex = 0
121pp_data->cap[1]->NotRange.Reserved3 = 0
122pp_data->cap[1]->NotRange.DataIndex = 0
123pp_data->cap[1]->NotRange.Reserved4 = 0
124pp_data->cap[1]->Button.LogicalMin = 0
125pp_data->cap[1]->Button.LogicalMax = 255
126pp_data->cap[1]->Units = 0
127pp_data->cap[1]->UnitsExp = 0
128
129# Feature hid_pp_cap struct:
130# Link Collections:
131pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
132pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
133pp_data->LinkCollectionArray[0]->Parent = 0
134pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
135pp_data->LinkCollectionArray[0]->NextSibling = 0
136pp_data->LinkCollectionArray[0]->FirstChild = 0
137pp_data->LinkCollectionArray[0]->CollectionType = 1
138pp_data->LinkCollectionArray[0]->IsAlias = 0
139pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_expected.rpt_desc
new file mode 100644
index 0000000..b1654e7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_expected.rpt_desc
@@ -0,0 +1,4 @@
10x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, 0x01, 0x85, 0x11, 0x09,
20x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x13,
30x81, 0x00, 0x09, 0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
40x08, 0x95, 0x13, 0x91, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_real.rpt_desc
new file mode 100644
index 0000000..68043e1
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C52F_0002_FF00_real.rpt_desc
@@ -0,0 +1,13 @@
1Usage Page (Vendor-Defined 1) 06 00 FF
2Usage (Vendor-Defined 2) 09 02
3Collection (Application) A1 01
4 Report ID (17) 85 11
5 Report Size (8) 75 08
6 Report Count (19) 95 13
7 Logical Minimum (0) 15 00
8 Logical Maximum (255) 26 FF 00
9 Usage (Vendor-Defined 2) 09 02
10 Input (Data,Ary,Abs) 81 00
11 Usage (Vendor-Defined 2) 09 02
12 Output (Data,Ary,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 00
13End Collection C0
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C.pp_data
new file mode 100644
index 0000000..5e44a31
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C.pp_data
@@ -0,0 +1,93 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC534
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2901
7dev->interface_number = 1
8dev->usage = 0x0001
9dev->usage_page = 0x000C
10dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col02#7&1ebb799e&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0x000C
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 5
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 1
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 1
29pp_data->caps_info[2]->LastCap = 1
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0068
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x000C
37pp_data->cap[0]->ReportID = 0x03
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 16
40pp_data->cap[0]->ReportCount = 2
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 32
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0005
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x000C
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x0001
70pp_data->cap[0]->Range.UsageMax = 0x028C
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 651
77pp_data->cap[0]->Button.LogicalMin = 1
78pp_data->cap[0]->Button.LogicalMax = 652
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83# Feature hid_pp_cap struct:
84# Link Collections:
85pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
86pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
87pp_data->LinkCollectionArray[0]->Parent = 0
88pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
89pp_data->LinkCollectionArray[0]->NextSibling = 0
90pp_data->LinkCollectionArray[0]->FirstChild = 0
91pp_data->LinkCollectionArray[0]->CollectionType = 1
92pp_data->LinkCollectionArray[0]->IsAlias = 0
93pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_expected.rpt_desc
new file mode 100644
index 0000000..85953ae
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_expected.rpt_desc
@@ -0,0 +1,3 @@
10x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x03, 0x19, 0x01,
20x2A, 0x8C, 0x02, 0x15, 0x01, 0x26, 0x8C, 0x02, 0x75, 0x10,
30x95, 0x02, 0x81, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_real.rpt_desc
new file mode 100644
index 0000000..e08f1f3
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_000C_real.rpt_desc
@@ -0,0 +1,18 @@
1macOS USB prober output for Logitech USB Receiver
2 05 0C 09 01 A1 01
3 85 03 75 10 95 02 15 01 26 8C 02 19 01 2A 8C 02 81 00
4 C0
5
6 Parser output:
70x05, 0x0C, // Usage Page (Consumer)
80x09, 0x01, // Usage (Consumer Control)
90xA1, 0x01, // Collection (Application)
100x85, 0x03, // Report ID (3)
110x75, 0x10, // Report Size (16)
120x95, 0x02, // Report Count (2)
130x15, 0x01, // Logical Minimum (1)
140x26, 0x8C, 0x02, // Logical Maximum (652)
150x19, 0x01, // Usage Minimum (Consumer Control)
160x2A, 0x8C, 0x02, // Usage Maximum (AC Send)
170x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
180xC0, // End Collection \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00.pp_data
new file mode 100644
index 0000000..6d42a15
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00.pp_data
@@ -0,0 +1,139 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC534
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2901
7dev->interface_number = 1
8dev->usage = 0x0001
9dev->usage_page = 0xFF00
10dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col04#7&1ebb799e&0&0003#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0xFF00
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 7
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 2
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 7
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 2
29pp_data->caps_info[2]->LastCap = 2
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x00D0
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFF00
37pp_data->cap[0]->ReportID = 0x10
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 6
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 48
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0007
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0xFF00
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0001
70pp_data->cap[0]->NotRange.Reserved1 = 0x0001
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 255
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83pp_data->cap[1]->UsagePage = 0xFF00
84pp_data->cap[1]->ReportID = 0x10
85pp_data->cap[1]->BitPosition = 0
86pp_data->cap[1]->BitSize = 8
87pp_data->cap[1]->ReportCount = 6
88pp_data->cap[1]->BytePosition = 0x0001
89pp_data->cap[1]->BitCount = 48
90pp_data->cap[1]->BitField = 0x00
91pp_data->cap[1]->NextBytePosition = 0x0007
92pp_data->cap[1]->LinkCollection = 0x0000
93pp_data->cap[1]->LinkUsagePage = 0xFF00
94pp_data->cap[1]->LinkUsage = 0x0001
95pp_data->cap[1]->IsMultipleItemsForArray = 0
96pp_data->cap[1]->IsButtonCap = 1
97pp_data->cap[1]->IsPadding = 0
98pp_data->cap[1]->IsAbsolute = 1
99pp_data->cap[1]->IsRange = 0
100pp_data->cap[1]->IsAlias = 0
101pp_data->cap[1]->IsStringRange = 0
102pp_data->cap[1]->IsDesignatorRange = 0
103pp_data->cap[1]->Reserved1 = 0x000000
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
105pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
106pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
116pp_data->cap[1]->NotRange.Usage = 0x0001
117pp_data->cap[1]->NotRange.Reserved1 = 0x0001
118pp_data->cap[1]->NotRange.StringIndex = 0
119pp_data->cap[1]->NotRange.Reserved2 = 0
120pp_data->cap[1]->NotRange.DesignatorIndex = 0
121pp_data->cap[1]->NotRange.Reserved3 = 0
122pp_data->cap[1]->NotRange.DataIndex = 0
123pp_data->cap[1]->NotRange.Reserved4 = 0
124pp_data->cap[1]->Button.LogicalMin = 0
125pp_data->cap[1]->Button.LogicalMax = 255
126pp_data->cap[1]->Units = 0
127pp_data->cap[1]->UnitsExp = 0
128
129# Feature hid_pp_cap struct:
130# Link Collections:
131pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
132pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
133pp_data->LinkCollectionArray[0]->Parent = 0
134pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
135pp_data->LinkCollectionArray[0]->NextSibling = 0
136pp_data->LinkCollectionArray[0]->FirstChild = 0
137pp_data->LinkCollectionArray[0]->CollectionType = 1
138pp_data->LinkCollectionArray[0]->IsAlias = 0
139pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_expected.rpt_desc
new file mode 100644
index 0000000..812bd2a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_expected.rpt_desc
@@ -0,0 +1,4 @@
10x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x09,
20x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x06,
30x81, 0x00, 0x09, 0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
40x08, 0x95, 0x06, 0x91, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_real.rpt_desc
new file mode 100644
index 0000000..953193c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0001_FF00_real.rpt_desc
@@ -0,0 +1,20 @@
1macOS USB prober output for Logitech USB Receiver
2
306 00 FF 09 01 A1 01 85 10 75 08 95 06
415 00 26 FF 00 09 01 81
500 09 01 91 00 C0
6
7Parser Output:
80x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
90x09, 0x01, // Usage (0x01)
100xA1, 0x01, // Collection (Application)
110x85, 0x10, // Report ID (16)
120x75, 0x08, // Report Size (8)
130x95, 0x06, // Report Count (6)
140x15, 0x00, // Logical Minimum (0)
150x26, 0xFF, 0x00, // Logical Maximum (255)
160x09, 0x01, // Usage (0x01)
170x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
180x09, 0x01, // Usage (0x01)
190x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
200xC0, // End Collection
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001.pp_data
new file mode 100644
index 0000000..f50d8a2
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001.pp_data
@@ -0,0 +1,302 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC534
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2901
7dev->interface_number = 1
8dev->usage = 0x0002
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col01#7&1ebb799e&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0002
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 5
20pp_data->caps_info[0]->NumberOfCaps = 5
21pp_data->caps_info[0]->ReportByteLength = 8
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 5
24pp_data->caps_info[1]->LastCap = 5
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 5
29pp_data->caps_info[2]->LastCap = 5
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0208
34pp_data->NumberLinkCollectionNodes = 2
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0009
37pp_data->cap[0]->ReportID = 0x02
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 16
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 16
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0003
45pp_data->cap[0]->LinkCollection = 0x0001
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x0001
70pp_data->cap[0]->Range.UsageMax = 0x0010
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 15
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x0001
83pp_data->cap[1]->ReportID = 0x02
84pp_data->cap[1]->BitPosition = 4
85pp_data->cap[1]->BitSize = 12
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0004
88pp_data->cap[1]->BitCount = 12
89pp_data->cap[1]->BitField = 0x06
90pp_data->cap[1]->NextBytePosition = 0x0006
91pp_data->cap[1]->LinkCollection = 0x0001
92pp_data->cap[1]->LinkUsagePage = 0x0001
93pp_data->cap[1]->LinkUsage = 0x0001
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 0
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 0
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x0031
116pp_data->cap[1]->NotRange.Reserved1 = 0x0031
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 16
122pp_data->cap[1]->NotRange.Reserved4 = 16
123pp_data->cap[1]->NotButton.HasNull = 0
124pp_data->cap[1]->NotButton.Reserved4 = 0x000000
125pp_data->cap[1]->NotButton.LogicalMin = -2047
126pp_data->cap[1]->NotButton.LogicalMax = 2047
127pp_data->cap[1]->NotButton.PhysicalMin = 0
128pp_data->cap[1]->NotButton.PhysicalMax = 0
129pp_data->cap[1]->Units = 0
130pp_data->cap[1]->UnitsExp = 0
131
132pp_data->cap[2]->UsagePage = 0x0001
133pp_data->cap[2]->ReportID = 0x02
134pp_data->cap[2]->BitPosition = 0
135pp_data->cap[2]->BitSize = 12
136pp_data->cap[2]->ReportCount = 1
137pp_data->cap[2]->BytePosition = 0x0003
138pp_data->cap[2]->BitCount = 12
139pp_data->cap[2]->BitField = 0x06
140pp_data->cap[2]->NextBytePosition = 0x0005
141pp_data->cap[2]->LinkCollection = 0x0001
142pp_data->cap[2]->LinkUsagePage = 0x0001
143pp_data->cap[2]->LinkUsage = 0x0001
144pp_data->cap[2]->IsMultipleItemsForArray = 0
145pp_data->cap[2]->IsButtonCap = 0
146pp_data->cap[2]->IsPadding = 0
147pp_data->cap[2]->IsAbsolute = 0
148pp_data->cap[2]->IsRange = 0
149pp_data->cap[2]->IsAlias = 0
150pp_data->cap[2]->IsStringRange = 0
151pp_data->cap[2]->IsDesignatorRange = 0
152pp_data->cap[2]->Reserved1 = 0x000000
153pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
154pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
155pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
156pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
157pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
158pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
159pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
160pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
161pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
162pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
163pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
164pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
165pp_data->cap[2]->NotRange.Usage = 0x0030
166pp_data->cap[2]->NotRange.Reserved1 = 0x0030
167pp_data->cap[2]->NotRange.StringIndex = 0
168pp_data->cap[2]->NotRange.Reserved2 = 0
169pp_data->cap[2]->NotRange.DesignatorIndex = 0
170pp_data->cap[2]->NotRange.Reserved3 = 0
171pp_data->cap[2]->NotRange.DataIndex = 17
172pp_data->cap[2]->NotRange.Reserved4 = 17
173pp_data->cap[2]->NotButton.HasNull = 0
174pp_data->cap[2]->NotButton.Reserved4 = 0x000000
175pp_data->cap[2]->NotButton.LogicalMin = -2047
176pp_data->cap[2]->NotButton.LogicalMax = 2047
177pp_data->cap[2]->NotButton.PhysicalMin = 0
178pp_data->cap[2]->NotButton.PhysicalMax = 0
179pp_data->cap[2]->Units = 0
180pp_data->cap[2]->UnitsExp = 0
181
182pp_data->cap[3]->UsagePage = 0x0001
183pp_data->cap[3]->ReportID = 0x02
184pp_data->cap[3]->BitPosition = 0
185pp_data->cap[3]->BitSize = 8
186pp_data->cap[3]->ReportCount = 1
187pp_data->cap[3]->BytePosition = 0x0006
188pp_data->cap[3]->BitCount = 8
189pp_data->cap[3]->BitField = 0x06
190pp_data->cap[3]->NextBytePosition = 0x0007
191pp_data->cap[3]->LinkCollection = 0x0001
192pp_data->cap[3]->LinkUsagePage = 0x0001
193pp_data->cap[3]->LinkUsage = 0x0001
194pp_data->cap[3]->IsMultipleItemsForArray = 0
195pp_data->cap[3]->IsButtonCap = 0
196pp_data->cap[3]->IsPadding = 0
197pp_data->cap[3]->IsAbsolute = 0
198pp_data->cap[3]->IsRange = 0
199pp_data->cap[3]->IsAlias = 0
200pp_data->cap[3]->IsStringRange = 0
201pp_data->cap[3]->IsDesignatorRange = 0
202pp_data->cap[3]->Reserved1 = 0x000000
203pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
204pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
205pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
206pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
207pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
208pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
209pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
210pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
211pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
212pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
213pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
214pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
215pp_data->cap[3]->NotRange.Usage = 0x0038
216pp_data->cap[3]->NotRange.Reserved1 = 0x0038
217pp_data->cap[3]->NotRange.StringIndex = 0
218pp_data->cap[3]->NotRange.Reserved2 = 0
219pp_data->cap[3]->NotRange.DesignatorIndex = 0
220pp_data->cap[3]->NotRange.Reserved3 = 0
221pp_data->cap[3]->NotRange.DataIndex = 18
222pp_data->cap[3]->NotRange.Reserved4 = 18
223pp_data->cap[3]->NotButton.HasNull = 0
224pp_data->cap[3]->NotButton.Reserved4 = 0x000000
225pp_data->cap[3]->NotButton.LogicalMin = -127
226pp_data->cap[3]->NotButton.LogicalMax = 127
227pp_data->cap[3]->NotButton.PhysicalMin = 0
228pp_data->cap[3]->NotButton.PhysicalMax = 0
229pp_data->cap[3]->Units = 0
230pp_data->cap[3]->UnitsExp = 0
231
232pp_data->cap[4]->UsagePage = 0x000C
233pp_data->cap[4]->ReportID = 0x02
234pp_data->cap[4]->BitPosition = 0
235pp_data->cap[4]->BitSize = 8
236pp_data->cap[4]->ReportCount = 1
237pp_data->cap[4]->BytePosition = 0x0007
238pp_data->cap[4]->BitCount = 8
239pp_data->cap[4]->BitField = 0x06
240pp_data->cap[4]->NextBytePosition = 0x0008
241pp_data->cap[4]->LinkCollection = 0x0001
242pp_data->cap[4]->LinkUsagePage = 0x0001
243pp_data->cap[4]->LinkUsage = 0x0001
244pp_data->cap[4]->IsMultipleItemsForArray = 0
245pp_data->cap[4]->IsButtonCap = 0
246pp_data->cap[4]->IsPadding = 0
247pp_data->cap[4]->IsAbsolute = 0
248pp_data->cap[4]->IsRange = 0
249pp_data->cap[4]->IsAlias = 0
250pp_data->cap[4]->IsStringRange = 0
251pp_data->cap[4]->IsDesignatorRange = 0
252pp_data->cap[4]->Reserved1 = 0x000000
253pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
254pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
255pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
256pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
257pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
258pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
259pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
260pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
261pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
262pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
263pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
264pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
265pp_data->cap[4]->NotRange.Usage = 0x0238
266pp_data->cap[4]->NotRange.Reserved1 = 0x0238
267pp_data->cap[4]->NotRange.StringIndex = 0
268pp_data->cap[4]->NotRange.Reserved2 = 0
269pp_data->cap[4]->NotRange.DesignatorIndex = 0
270pp_data->cap[4]->NotRange.Reserved3 = 0
271pp_data->cap[4]->NotRange.DataIndex = 19
272pp_data->cap[4]->NotRange.Reserved4 = 19
273pp_data->cap[4]->NotButton.HasNull = 0
274pp_data->cap[4]->NotButton.Reserved4 = 0x000000
275pp_data->cap[4]->NotButton.LogicalMin = -127
276pp_data->cap[4]->NotButton.LogicalMax = 127
277pp_data->cap[4]->NotButton.PhysicalMin = 0
278pp_data->cap[4]->NotButton.PhysicalMax = 0
279pp_data->cap[4]->Units = 0
280pp_data->cap[4]->UnitsExp = 0
281
282# Output hid_pp_cap struct:
283# Feature hid_pp_cap struct:
284# Link Collections:
285pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
286pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
287pp_data->LinkCollectionArray[0]->Parent = 0
288pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
289pp_data->LinkCollectionArray[0]->NextSibling = 0
290pp_data->LinkCollectionArray[0]->FirstChild = 1
291pp_data->LinkCollectionArray[0]->CollectionType = 1
292pp_data->LinkCollectionArray[0]->IsAlias = 0
293pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
294pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
295pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
296pp_data->LinkCollectionArray[1]->Parent = 0
297pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
298pp_data->LinkCollectionArray[1]->NextSibling = 0
299pp_data->LinkCollectionArray[1]->FirstChild = 0
300pp_data->LinkCollectionArray[1]->CollectionType = 0
301pp_data->LinkCollectionArray[1]->IsAlias = 0
302pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_expected.rpt_desc
new file mode 100644
index 0000000..48701c6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_expected.rpt_desc
@@ -0,0 +1,8 @@
10x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
20x85, 0x02, 0x05, 0x09, 0x19, 0x01, 0x29, 0x10, 0x15, 0x00,
30x25, 0x01, 0x75, 0x01, 0x95, 0x10, 0x81, 0x02, 0x05, 0x01,
40x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xF8, 0x26, 0xFF, 0x07,
50x75, 0x0C, 0x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81,
60x25, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0x05, 0x0C,
70x0A, 0x38, 0x02, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95,
80x01, 0x81, 0x06, 0xC0, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_real.rpt_desc
new file mode 100644
index 0000000..1c5dea9
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_0001_real.rpt_desc
@@ -0,0 +1,44 @@
1
205 01 09 02 A1 01 85 02 09 01 A1 00 05 09 19 01
329 10 15 00 25 01 95 10 75 01 81 02 05 01 16 01
4F8 26 FF 07 75 0C 95 02 09 30 09 31 81 06 15 81
525 7F 75 08 95 01 09 38 81 06 05 0C 0A 38 02 95
601 81 06 C0 C0
7
8Parser Output:
90x05, 0x01, // Usage Page (Generic Desktop Ctrls)
100x09, 0x02, // Usage (Mouse)
110xA1, 0x01, // Collection (Application)
120x85, 0x02, // Report ID (2)
130x09, 0x01, // Usage (Pointer)
140xA1, 0x00, // Collection (Physical)
150x05, 0x09, // Usage Page (Button)
160x19, 0x01, // Usage Minimum (0x01)
170x29, 0x10, // Usage Maximum (0x10)
180x15, 0x00, // Logical Minimum (0)
190x25, 0x01, // Logical Maximum (1)
200x95, 0x10, // Report Count (16)
210x75, 0x01, // Report Size (1)
220x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
230x05, 0x01, // Usage Page (Generic Desktop Ctrls)
240x16, 0x01, 0xF8, // Logical Minimum (-2047)
250x26, 0xFF, 0x07, // Logical Maximum (2047)
260x75, 0x0C, // Report Size (12)
270x95, 0x02, // Report Count (2)
280x09, 0x30, // Usage (X)
290x09, 0x31, // Usage (Y)
300x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
310x15, 0x81, // Logical Minimum (-127)
320x25, 0x7F, // Logical Maximum (127)
330x75, 0x08, // Report Size (8)
340x95, 0x01, // Report Count (1)
350x09, 0x38, // Usage (Wheel)
360x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
370x05, 0x0C, // Usage Page (Consumer)
380x0A, 0x38, 0x02, // Usage (AC Pan)
390x95, 0x01, // Report Count (1)
400x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
410xC0, // End Collection
420xC0, // End Collection
43
44// 69 bytes
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00.pp_data
new file mode 100644
index 0000000..b5fae3a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00.pp_data
@@ -0,0 +1,139 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC534
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2901
7dev->interface_number = 1
8dev->usage = 0x0002
9dev->usage_page = 0xFF00
10dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col05#7&1ebb799e&0&0004#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0002
15pp_data->UsagePage = 0xFF00
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 1
20pp_data->caps_info[0]->NumberOfCaps = 1
21pp_data->caps_info[0]->ReportByteLength = 20
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 1
24pp_data->caps_info[1]->LastCap = 2
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 20
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 2
29pp_data->caps_info[2]->LastCap = 2
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x00D0
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFF00
37pp_data->cap[0]->ReportID = 0x11
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 19
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 152
43pp_data->cap[0]->BitField = 0x00
44pp_data->cap[0]->NextBytePosition = 0x0014
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0xFF00
47pp_data->cap[0]->LinkUsage = 0x0002
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0002
70pp_data->cap[0]->NotRange.Reserved1 = 0x0002
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 255
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82# Output hid_pp_cap struct:
83pp_data->cap[1]->UsagePage = 0xFF00
84pp_data->cap[1]->ReportID = 0x11
85pp_data->cap[1]->BitPosition = 0
86pp_data->cap[1]->BitSize = 8
87pp_data->cap[1]->ReportCount = 19
88pp_data->cap[1]->BytePosition = 0x0001
89pp_data->cap[1]->BitCount = 152
90pp_data->cap[1]->BitField = 0x00
91pp_data->cap[1]->NextBytePosition = 0x0014
92pp_data->cap[1]->LinkCollection = 0x0000
93pp_data->cap[1]->LinkUsagePage = 0xFF00
94pp_data->cap[1]->LinkUsage = 0x0002
95pp_data->cap[1]->IsMultipleItemsForArray = 0
96pp_data->cap[1]->IsButtonCap = 1
97pp_data->cap[1]->IsPadding = 0
98pp_data->cap[1]->IsAbsolute = 1
99pp_data->cap[1]->IsRange = 0
100pp_data->cap[1]->IsAlias = 0
101pp_data->cap[1]->IsStringRange = 0
102pp_data->cap[1]->IsDesignatorRange = 0
103pp_data->cap[1]->Reserved1 = 0x000000
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
105pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
106pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
116pp_data->cap[1]->NotRange.Usage = 0x0002
117pp_data->cap[1]->NotRange.Reserved1 = 0x0002
118pp_data->cap[1]->NotRange.StringIndex = 0
119pp_data->cap[1]->NotRange.Reserved2 = 0
120pp_data->cap[1]->NotRange.DesignatorIndex = 0
121pp_data->cap[1]->NotRange.Reserved3 = 0
122pp_data->cap[1]->NotRange.DataIndex = 0
123pp_data->cap[1]->NotRange.Reserved4 = 0
124pp_data->cap[1]->Button.LogicalMin = 0
125pp_data->cap[1]->Button.LogicalMax = 255
126pp_data->cap[1]->Units = 0
127pp_data->cap[1]->UnitsExp = 0
128
129# Feature hid_pp_cap struct:
130# Link Collections:
131pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
132pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
133pp_data->LinkCollectionArray[0]->Parent = 0
134pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
135pp_data->LinkCollectionArray[0]->NextSibling = 0
136pp_data->LinkCollectionArray[0]->FirstChild = 0
137pp_data->LinkCollectionArray[0]->CollectionType = 1
138pp_data->LinkCollectionArray[0]->IsAlias = 0
139pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_expected.rpt_desc
new file mode 100644
index 0000000..b1654e7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_expected.rpt_desc
@@ -0,0 +1,4 @@
10x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, 0x01, 0x85, 0x11, 0x09,
20x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x13,
30x81, 0x00, 0x09, 0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
40x08, 0x95, 0x13, 0x91, 0x00, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_real.rpt_desc
new file mode 100644
index 0000000..42a0ad8
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0002_FF00_real.rpt_desc
@@ -0,0 +1,22 @@
1macOS USB prober output for Logitech USB Receiver
2
306 00 FF 09 02 A1 01 85 11
475 08 95 13 15 00 26 FF
500 09 02 81 00 09 02 91 00 C0
6
7Parser output:
80x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
90x09, 0x02, // Usage (0x02)
100xA1, 0x01, // Collection (Application)
110x85, 0x11, // Report ID (17)
120x75, 0x08, // Report Size (8)
130x95, 0x13, // Report Count (19)
140x15, 0x00, // Logical Minimum (0)
150x26, 0xFF, 0x00, // Logical Maximum (255)
160x09, 0x02, // Usage (0x02)
170x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
180x09, 0x02, // Usage (0x02)
190x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
200xC0, // End Collection
21
22// 27 bytes
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001.pp_data
new file mode 100644
index 0000000..2b42d5f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001.pp_data
@@ -0,0 +1,185 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC534
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2901
7dev->interface_number = 0
8dev->usage = 0x0006
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#vid_046d&pid_c534&mi_00#7&51bc424&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}\kbd"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0006
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 2
20pp_data->caps_info[0]->NumberOfCaps = 2
21pp_data->caps_info[0]->ReportByteLength = 9
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 2
24pp_data->caps_info[1]->LastCap = 3
25pp_data->caps_info[1]->NumberOfCaps = 1
26pp_data->caps_info[1]->ReportByteLength = 2
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 3
29pp_data->caps_info[2]->LastCap = 3
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0138
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0007
37pp_data->cap[0]->ReportID = 0x00
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 8
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 8
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0006
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 1
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->Range.UsageMin = 0x00E0
70pp_data->cap[0]->Range.UsageMax = 0x00E7
71pp_data->cap[0]->Range.StringMin = 0
72pp_data->cap[0]->Range.StringMax = 0
73pp_data->cap[0]->Range.DesignatorMin = 0
74pp_data->cap[0]->Range.DesignatorMax = 0
75pp_data->cap[0]->Range.DataIndexMin = 0
76pp_data->cap[0]->Range.DataIndexMax = 7
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x0007
83pp_data->cap[1]->ReportID = 0x00
84pp_data->cap[1]->BitPosition = 0
85pp_data->cap[1]->BitSize = 8
86pp_data->cap[1]->ReportCount = 6
87pp_data->cap[1]->BytePosition = 0x0003
88pp_data->cap[1]->BitCount = 48
89pp_data->cap[1]->BitField = 0x00
90pp_data->cap[1]->NextBytePosition = 0x0009
91pp_data->cap[1]->LinkCollection = 0x0000
92pp_data->cap[1]->LinkUsagePage = 0x0001
93pp_data->cap[1]->LinkUsage = 0x0006
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 1
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 1
98pp_data->cap[1]->IsRange = 1
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->Range.UsageMin = 0x0000
116pp_data->cap[1]->Range.UsageMax = 0x00A4
117pp_data->cap[1]->Range.StringMin = 0
118pp_data->cap[1]->Range.StringMax = 0
119pp_data->cap[1]->Range.DesignatorMin = 0
120pp_data->cap[1]->Range.DesignatorMax = 0
121pp_data->cap[1]->Range.DataIndexMin = 8
122pp_data->cap[1]->Range.DataIndexMax = 172
123pp_data->cap[1]->Button.LogicalMin = 0
124pp_data->cap[1]->Button.LogicalMax = 164
125pp_data->cap[1]->Units = 0
126pp_data->cap[1]->UnitsExp = 0
127
128# Output hid_pp_cap struct:
129pp_data->cap[2]->UsagePage = 0x0008
130pp_data->cap[2]->ReportID = 0x00
131pp_data->cap[2]->BitPosition = 0
132pp_data->cap[2]->BitSize = 1
133pp_data->cap[2]->ReportCount = 5
134pp_data->cap[2]->BytePosition = 0x0001
135pp_data->cap[2]->BitCount = 5
136pp_data->cap[2]->BitField = 0x02
137pp_data->cap[2]->NextBytePosition = 0x0002
138pp_data->cap[2]->LinkCollection = 0x0000
139pp_data->cap[2]->LinkUsagePage = 0x0001
140pp_data->cap[2]->LinkUsage = 0x0006
141pp_data->cap[2]->IsMultipleItemsForArray = 0
142pp_data->cap[2]->IsButtonCap = 1
143pp_data->cap[2]->IsPadding = 0
144pp_data->cap[2]->IsAbsolute = 1
145pp_data->cap[2]->IsRange = 1
146pp_data->cap[2]->IsAlias = 0
147pp_data->cap[2]->IsStringRange = 0
148pp_data->cap[2]->IsDesignatorRange = 0
149pp_data->cap[2]->Reserved1 = 0x000000
150pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
151pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
152pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
153pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
154pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
155pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
156pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
157pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
158pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
159pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
160pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
161pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
162pp_data->cap[2]->Range.UsageMin = 0x0001
163pp_data->cap[2]->Range.UsageMax = 0x0005
164pp_data->cap[2]->Range.StringMin = 0
165pp_data->cap[2]->Range.StringMax = 0
166pp_data->cap[2]->Range.DesignatorMin = 0
167pp_data->cap[2]->Range.DesignatorMax = 0
168pp_data->cap[2]->Range.DataIndexMin = 0
169pp_data->cap[2]->Range.DataIndexMax = 4
170pp_data->cap[2]->Button.LogicalMin = 0
171pp_data->cap[2]->Button.LogicalMax = 0
172pp_data->cap[2]->Units = 0
173pp_data->cap[2]->UnitsExp = 0
174
175# Feature hid_pp_cap struct:
176# Link Collections:
177pp_data->LinkCollectionArray[0]->LinkUsage = 0x0006
178pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
179pp_data->LinkCollectionArray[0]->Parent = 0
180pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
181pp_data->LinkCollectionArray[0]->NextSibling = 0
182pp_data->LinkCollectionArray[0]->FirstChild = 0
183pp_data->LinkCollectionArray[0]->CollectionType = 1
184pp_data->LinkCollectionArray[0]->IsAlias = 0
185pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_expected.rpt_desc
new file mode 100644
index 0000000..d41d471
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_expected.rpt_desc
@@ -0,0 +1,7 @@
10x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0,
20x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
30x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03, 0x19, 0x00,
40x29, 0xA4, 0x15, 0x00, 0x26, 0xA4, 0x00, 0x75, 0x08, 0x95,
50x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x15,
60x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x05, 0x91, 0x02, 0x75,
70x03, 0x95, 0x01, 0x91, 0x03, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_real.rpt_desc
new file mode 100644
index 0000000..d65aa57
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0006_0001_real.rpt_desc
@@ -0,0 +1,42 @@
1macOS USB prober output for Logitech USB Receiver
2
3
4Type: 0x22 (Report Descriptor)
5Length (and contents): 59
6 Raw Descriptor (hex) 0000: 05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
7 Raw Descriptor (hex) 0010: 75 01 95 08 81 02 81 03 95 05 05 08 19 01 29 05
8 Raw Descriptor (hex) 0020: 91 02 95 01 75 03 91 01 95 06 75 08 15 00 26 A4
9 Raw Descriptor (hex) 0030: 00 05 07 19 00 2A A4 00 81 00 C0
10
11Parser output:
120x05, 0x01, // Usage Page (Generic Desktop Ctrls)
130x09, 0x06, // Usage (Keyboard)
140xA1, 0x01, // Collection (Application)
150x05, 0x07, // Usage Page (Kbrd/Keypad)
160x19, 0xE0, // Usage Minimum (0xE0)
170x29, 0xE7, // Usage Maximum (0xE7)
180x15, 0x00, // Logical Minimum (0)
190x25, 0x01, // Logical Maximum (1)
200x75, 0x01, // Report Size (1)
210x95, 0x08, // Report Count (8)
220x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
230x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
240x95, 0x05, // Report Count (5)
250x05, 0x08, // Usage Page (LEDs)
260x19, 0x01, // Usage Minimum (Num Lock)
270x29, 0x05, // Usage Maximum (Kana)
280x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
290x95, 0x01, // Report Count (1)
300x75, 0x03, // Report Size (3)
310x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
320x95, 0x06, // Report Count (6)
330x75, 0x08, // Report Size (8)
340x15, 0x00, // Logical Minimum (0)
350x26, 0xA4, 0x00, // Logical Maximum (164)
360x05, 0x07, // Usage Page (Kbrd/Keypad)
370x19, 0x00, // Usage Minimum (0x00)
380x2A, 0xA4, 0x00, // Usage Maximum (0xA4)
390x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
400xC0, // End Collection
41
42// 59 bytes
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001.pp_data
new file mode 100644
index 0000000..a829f70
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001.pp_data
@@ -0,0 +1,185 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x046D
3dev->product_id = 0xC534
4dev->manufacturer_string = "Logitech"
5dev->product_string = "USB Receiver"
6dev->release_number = 0x2901
7dev->interface_number = 1
8dev->usage = 0x0080
9dev->usage_page = 0x0001
10dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col03#7&1ebb799e&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0080
15pp_data->UsagePage = 0x0001
16pp_data->Reserved = 0x00038000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 3
20pp_data->caps_info[0]->NumberOfCaps = 3
21pp_data->caps_info[0]->ReportByteLength = 2
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 3
24pp_data->caps_info[1]->LastCap = 3
25pp_data->caps_info[1]->NumberOfCaps = 0
26pp_data->caps_info[1]->ReportByteLength = 0
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 3
29pp_data->caps_info[2]->LastCap = 3
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0138
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x0001
37pp_data->cap[0]->ReportID = 0x04
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 2
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 2
43pp_data->cap[0]->BitField = 0x60
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x0001
47pp_data->cap[0]->LinkUsage = 0x0080
48pp_data->cap[0]->IsMultipleItemsForArray = 1
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0083
70pp_data->cap[0]->NotRange.Reserved1 = 0x0083
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 2
76pp_data->cap[0]->NotRange.Reserved4 = 2
77pp_data->cap[0]->Button.LogicalMin = 1
78pp_data->cap[0]->Button.LogicalMax = 3
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x0001
83pp_data->cap[1]->ReportID = 0x04
84pp_data->cap[1]->BitPosition = 0
85pp_data->cap[1]->BitSize = 2
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0001
88pp_data->cap[1]->BitCount = 2
89pp_data->cap[1]->BitField = 0x60
90pp_data->cap[1]->NextBytePosition = 0x0002
91pp_data->cap[1]->LinkCollection = 0x0000
92pp_data->cap[1]->LinkUsagePage = 0x0001
93pp_data->cap[1]->LinkUsage = 0x0080
94pp_data->cap[1]->IsMultipleItemsForArray = 1
95pp_data->cap[1]->IsButtonCap = 1
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 1
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x0081
116pp_data->cap[1]->NotRange.Reserved1 = 0x0081
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 1
122pp_data->cap[1]->NotRange.Reserved4 = 1
123pp_data->cap[1]->Button.LogicalMin = 1
124pp_data->cap[1]->Button.LogicalMax = 3
125pp_data->cap[1]->Units = 0
126pp_data->cap[1]->UnitsExp = 0
127
128pp_data->cap[2]->UsagePage = 0x0001
129pp_data->cap[2]->ReportID = 0x04
130pp_data->cap[2]->BitPosition = 0
131pp_data->cap[2]->BitSize = 2
132pp_data->cap[2]->ReportCount = 1
133pp_data->cap[2]->BytePosition = 0x0001
134pp_data->cap[2]->BitCount = 2
135pp_data->cap[2]->BitField = 0x60
136pp_data->cap[2]->NextBytePosition = 0x0002
137pp_data->cap[2]->LinkCollection = 0x0000
138pp_data->cap[2]->LinkUsagePage = 0x0001
139pp_data->cap[2]->LinkUsage = 0x0080
140pp_data->cap[2]->IsMultipleItemsForArray = 0
141pp_data->cap[2]->IsButtonCap = 1
142pp_data->cap[2]->IsPadding = 0
143pp_data->cap[2]->IsAbsolute = 1
144pp_data->cap[2]->IsRange = 0
145pp_data->cap[2]->IsAlias = 0
146pp_data->cap[2]->IsStringRange = 0
147pp_data->cap[2]->IsDesignatorRange = 0
148pp_data->cap[2]->Reserved1 = 0x000000
149pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
150pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
151pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
152pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
153pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
154pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
155pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
156pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
157pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
158pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
159pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
160pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
161pp_data->cap[2]->NotRange.Usage = 0x0082
162pp_data->cap[2]->NotRange.Reserved1 = 0x0082
163pp_data->cap[2]->NotRange.StringIndex = 0
164pp_data->cap[2]->NotRange.Reserved2 = 0
165pp_data->cap[2]->NotRange.DesignatorIndex = 0
166pp_data->cap[2]->NotRange.Reserved3 = 0
167pp_data->cap[2]->NotRange.DataIndex = 0
168pp_data->cap[2]->NotRange.Reserved4 = 0
169pp_data->cap[2]->Button.LogicalMin = 1
170pp_data->cap[2]->Button.LogicalMax = 3
171pp_data->cap[2]->Units = 0
172pp_data->cap[2]->UnitsExp = 0
173
174# Output hid_pp_cap struct:
175# Feature hid_pp_cap struct:
176# Link Collections:
177pp_data->LinkCollectionArray[0]->LinkUsage = 0x0080
178pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
179pp_data->LinkCollectionArray[0]->Parent = 0
180pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
181pp_data->LinkCollectionArray[0]->NextSibling = 0
182pp_data->LinkCollectionArray[0]->FirstChild = 0
183pp_data->LinkCollectionArray[0]->CollectionType = 1
184pp_data->LinkCollectionArray[0]->IsAlias = 0
185pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_expected.rpt_desc
new file mode 100644
index 0000000..e7a9677
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_expected.rpt_desc
@@ -0,0 +1,4 @@
10x05, 0x01, 0x09, 0x80, 0xA1, 0x01, 0x85, 0x04, 0x09, 0x82,
20x09, 0x81, 0x09, 0x83, 0x15, 0x01, 0x25, 0x03, 0x75, 0x02,
30x95, 0x01, 0x81, 0x60, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03,
40xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_real.rpt_desc
new file mode 100644
index 0000000..7ebe8c9
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/046D_C534_0080_0001_real.rpt_desc
@@ -0,0 +1,22 @@
1
205 01 09 80 A1 01 85 04 75 02 95 01 15 01 25 03
309 82 09 81 09 83 81 60 75 06 81 03 C0
4
5Parser output:
60x05, 0x01, // Usage Page (Generic Desktop Ctrls)
70x09, 0x80, // Usage (Sys Control)
80xA1, 0x01, // Collection (Application)
90x85, 0x04, // Report ID (4)
100x75, 0x02, // Report Size (2)
110x95, 0x01, // Report Count (1)
120x15, 0x01, // Logical Minimum (1)
130x25, 0x03, // Logical Maximum (3)
140x09, 0x82, // Usage (Sys Sleep)
150x09, 0x81, // Usage (Sys Power Down)
160x09, 0x83, // Usage (Sys Wake Up)
170x81, 0x60, // Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State)
180x75, 0x06, // Report Size (6)
190x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
200xC0, // End Collection
21
22// 29 bytes
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C.pp_data
new file mode 100644
index 0000000..87da2b2
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C.pp_data
@@ -0,0 +1,385 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x047F
3dev->product_id = 0xC056
4dev->manufacturer_string = "Plantronics"
5dev->product_string = "Plantronics Blackwire 3220 Series"
6dev->release_number = 0x0210
7dev->interface_number = 3
8dev->usage = 0x0001
9dev->usage_page = 0x000C
10dev->path = "\\?\hid#vid_047f&pid_c056&mi_03&col01#f&39e6f119&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0001
15pp_data->UsagePage = 0x000C
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 5
20pp_data->caps_info[0]->NumberOfCaps = 5
21pp_data->caps_info[0]->ReportByteLength = 33
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 5
24pp_data->caps_info[1]->LastCap = 7
25pp_data->caps_info[1]->NumberOfCaps = 2
26pp_data->caps_info[1]->ReportByteLength = 37
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 7
29pp_data->caps_info[2]->LastCap = 7
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x02D8
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x000C
37pp_data->cap[0]->ReportID = 0x01
38pp_data->cap[0]->BitPosition = 1
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 1
43pp_data->cap[0]->BitField = 0x06
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x000C
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 0
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x00EA
70pp_data->cap[0]->NotRange.Reserved1 = 0x00EA
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x000C
83pp_data->cap[1]->ReportID = 0x01
84pp_data->cap[1]->BitPosition = 0
85pp_data->cap[1]->BitSize = 1
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0001
88pp_data->cap[1]->BitCount = 1
89pp_data->cap[1]->BitField = 0x06
90pp_data->cap[1]->NextBytePosition = 0x0002
91pp_data->cap[1]->LinkCollection = 0x0000
92pp_data->cap[1]->LinkUsagePage = 0x000C
93pp_data->cap[1]->LinkUsage = 0x0001
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 1
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 0
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x00E9
116pp_data->cap[1]->NotRange.Reserved1 = 0x00E9
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 1
122pp_data->cap[1]->NotRange.Reserved4 = 1
123pp_data->cap[1]->Button.LogicalMin = 0
124pp_data->cap[1]->Button.LogicalMax = 0
125pp_data->cap[1]->Units = 0
126pp_data->cap[1]->UnitsExp = 0
127
128pp_data->cap[2]->UsagePage = 0x000C
129pp_data->cap[2]->ReportID = 0x02
130pp_data->cap[2]->BitPosition = 0
131pp_data->cap[2]->BitSize = 1
132pp_data->cap[2]->ReportCount = 16
133pp_data->cap[2]->BytePosition = 0x0001
134pp_data->cap[2]->BitCount = 16
135pp_data->cap[2]->BitField = 0x02
136pp_data->cap[2]->NextBytePosition = 0x0003
137pp_data->cap[2]->LinkCollection = 0x0000
138pp_data->cap[2]->LinkUsagePage = 0x000C
139pp_data->cap[2]->LinkUsage = 0x0001
140pp_data->cap[2]->IsMultipleItemsForArray = 0
141pp_data->cap[2]->IsButtonCap = 1
142pp_data->cap[2]->IsPadding = 0
143pp_data->cap[2]->IsAbsolute = 1
144pp_data->cap[2]->IsRange = 0
145pp_data->cap[2]->IsAlias = 0
146pp_data->cap[2]->IsStringRange = 0
147pp_data->cap[2]->IsDesignatorRange = 0
148pp_data->cap[2]->Reserved1 = 0x000000
149pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
150pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
151pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
152pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
153pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
154pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
155pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
156pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
157pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
158pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
159pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
160pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
161pp_data->cap[2]->NotRange.Usage = 0x0000
162pp_data->cap[2]->NotRange.Reserved1 = 0x0000
163pp_data->cap[2]->NotRange.StringIndex = 0
164pp_data->cap[2]->NotRange.Reserved2 = 0
165pp_data->cap[2]->NotRange.DesignatorIndex = 0
166pp_data->cap[2]->NotRange.Reserved3 = 0
167pp_data->cap[2]->NotRange.DataIndex = 2
168pp_data->cap[2]->NotRange.Reserved4 = 2
169pp_data->cap[2]->Button.LogicalMin = 0
170pp_data->cap[2]->Button.LogicalMax = 0
171pp_data->cap[2]->Units = 0
172pp_data->cap[2]->UnitsExp = 0
173
174pp_data->cap[3]->UsagePage = 0x000C
175pp_data->cap[3]->ReportID = 0x05
176pp_data->cap[3]->BitPosition = 0
177pp_data->cap[3]->BitSize = 8
178pp_data->cap[3]->ReportCount = 32
179pp_data->cap[3]->BytePosition = 0x0001
180pp_data->cap[3]->BitCount = 256
181pp_data->cap[3]->BitField = 0x02
182pp_data->cap[3]->NextBytePosition = 0x0021
183pp_data->cap[3]->LinkCollection = 0x0000
184pp_data->cap[3]->LinkUsagePage = 0x000C
185pp_data->cap[3]->LinkUsage = 0x0001
186pp_data->cap[3]->IsMultipleItemsForArray = 0
187pp_data->cap[3]->IsButtonCap = 0
188pp_data->cap[3]->IsPadding = 0
189pp_data->cap[3]->IsAbsolute = 1
190pp_data->cap[3]->IsRange = 0
191pp_data->cap[3]->IsAlias = 0
192pp_data->cap[3]->IsStringRange = 0
193pp_data->cap[3]->IsDesignatorRange = 0
194pp_data->cap[3]->Reserved1 = 0x000000
195pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
196pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
197pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
198pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
199pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
200pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
201pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
202pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
203pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
204pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
205pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
206pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
207pp_data->cap[3]->NotRange.Usage = 0x0000
208pp_data->cap[3]->NotRange.Reserved1 = 0x0000
209pp_data->cap[3]->NotRange.StringIndex = 0
210pp_data->cap[3]->NotRange.Reserved2 = 0
211pp_data->cap[3]->NotRange.DesignatorIndex = 0
212pp_data->cap[3]->NotRange.Reserved3 = 0
213pp_data->cap[3]->NotRange.DataIndex = 3
214pp_data->cap[3]->NotRange.Reserved4 = 3
215pp_data->cap[3]->NotButton.HasNull = 0
216pp_data->cap[3]->NotButton.Reserved4 = 0x000000
217pp_data->cap[3]->NotButton.LogicalMin = 0
218pp_data->cap[3]->NotButton.LogicalMax = 1
219pp_data->cap[3]->NotButton.PhysicalMin = 0
220pp_data->cap[3]->NotButton.PhysicalMax = 0
221pp_data->cap[3]->Units = 0
222pp_data->cap[3]->UnitsExp = 0
223
224pp_data->cap[4]->UsagePage = 0x000C
225pp_data->cap[4]->ReportID = 0x07
226pp_data->cap[4]->BitPosition = 0
227pp_data->cap[4]->BitSize = 8
228pp_data->cap[4]->ReportCount = 32
229pp_data->cap[4]->BytePosition = 0x0001
230pp_data->cap[4]->BitCount = 256
231pp_data->cap[4]->BitField = 0x02
232pp_data->cap[4]->NextBytePosition = 0x0021
233pp_data->cap[4]->LinkCollection = 0x0000
234pp_data->cap[4]->LinkUsagePage = 0x000C
235pp_data->cap[4]->LinkUsage = 0x0001
236pp_data->cap[4]->IsMultipleItemsForArray = 0
237pp_data->cap[4]->IsButtonCap = 0
238pp_data->cap[4]->IsPadding = 0
239pp_data->cap[4]->IsAbsolute = 1
240pp_data->cap[4]->IsRange = 0
241pp_data->cap[4]->IsAlias = 0
242pp_data->cap[4]->IsStringRange = 0
243pp_data->cap[4]->IsDesignatorRange = 0
244pp_data->cap[4]->Reserved1 = 0x000000
245pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
246pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
247pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
248pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
249pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
250pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
251pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
252pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
253pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
254pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
255pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
256pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
257pp_data->cap[4]->NotRange.Usage = 0x0000
258pp_data->cap[4]->NotRange.Reserved1 = 0x0000
259pp_data->cap[4]->NotRange.StringIndex = 0
260pp_data->cap[4]->NotRange.Reserved2 = 0
261pp_data->cap[4]->NotRange.DesignatorIndex = 0
262pp_data->cap[4]->NotRange.Reserved3 = 0
263pp_data->cap[4]->NotRange.DataIndex = 4
264pp_data->cap[4]->NotRange.Reserved4 = 4
265pp_data->cap[4]->NotButton.HasNull = 0
266pp_data->cap[4]->NotButton.Reserved4 = 0x000000
267pp_data->cap[4]->NotButton.LogicalMin = 0
268pp_data->cap[4]->NotButton.LogicalMax = 1
269pp_data->cap[4]->NotButton.PhysicalMin = 0
270pp_data->cap[4]->NotButton.PhysicalMax = 0
271pp_data->cap[4]->Units = 0
272pp_data->cap[4]->UnitsExp = 0
273
274# Output hid_pp_cap struct:
275pp_data->cap[5]->UsagePage = 0x000C
276pp_data->cap[5]->ReportID = 0x04
277pp_data->cap[5]->BitPosition = 0
278pp_data->cap[5]->BitSize = 8
279pp_data->cap[5]->ReportCount = 36
280pp_data->cap[5]->BytePosition = 0x0001
281pp_data->cap[5]->BitCount = 288
282pp_data->cap[5]->BitField = 0x02
283pp_data->cap[5]->NextBytePosition = 0x0025
284pp_data->cap[5]->LinkCollection = 0x0000
285pp_data->cap[5]->LinkUsagePage = 0x000C
286pp_data->cap[5]->LinkUsage = 0x0001
287pp_data->cap[5]->IsMultipleItemsForArray = 0
288pp_data->cap[5]->IsButtonCap = 0
289pp_data->cap[5]->IsPadding = 0
290pp_data->cap[5]->IsAbsolute = 1
291pp_data->cap[5]->IsRange = 0
292pp_data->cap[5]->IsAlias = 0
293pp_data->cap[5]->IsStringRange = 0
294pp_data->cap[5]->IsDesignatorRange = 0
295pp_data->cap[5]->Reserved1 = 0x000000
296pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
297pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
298pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
299pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
300pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
301pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
302pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
303pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
304pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
305pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
306pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
307pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
308pp_data->cap[5]->NotRange.Usage = 0x0000
309pp_data->cap[5]->NotRange.Reserved1 = 0x0000
310pp_data->cap[5]->NotRange.StringIndex = 0
311pp_data->cap[5]->NotRange.Reserved2 = 0
312pp_data->cap[5]->NotRange.DesignatorIndex = 0
313pp_data->cap[5]->NotRange.Reserved3 = 0
314pp_data->cap[5]->NotRange.DataIndex = 0
315pp_data->cap[5]->NotRange.Reserved4 = 0
316pp_data->cap[5]->NotButton.HasNull = 0
317pp_data->cap[5]->NotButton.Reserved4 = 0x000000
318pp_data->cap[5]->NotButton.LogicalMin = 0
319pp_data->cap[5]->NotButton.LogicalMax = 1
320pp_data->cap[5]->NotButton.PhysicalMin = 0
321pp_data->cap[5]->NotButton.PhysicalMax = 0
322pp_data->cap[5]->Units = 0
323pp_data->cap[5]->UnitsExp = 0
324
325pp_data->cap[6]->UsagePage = 0x000C
326pp_data->cap[6]->ReportID = 0x06
327pp_data->cap[6]->BitPosition = 0
328pp_data->cap[6]->BitSize = 8
329pp_data->cap[6]->ReportCount = 36
330pp_data->cap[6]->BytePosition = 0x0001
331pp_data->cap[6]->BitCount = 288
332pp_data->cap[6]->BitField = 0x02
333pp_data->cap[6]->NextBytePosition = 0x0025
334pp_data->cap[6]->LinkCollection = 0x0000
335pp_data->cap[6]->LinkUsagePage = 0x000C
336pp_data->cap[6]->LinkUsage = 0x0001
337pp_data->cap[6]->IsMultipleItemsForArray = 0
338pp_data->cap[6]->IsButtonCap = 0
339pp_data->cap[6]->IsPadding = 0
340pp_data->cap[6]->IsAbsolute = 1
341pp_data->cap[6]->IsRange = 0
342pp_data->cap[6]->IsAlias = 0
343pp_data->cap[6]->IsStringRange = 0
344pp_data->cap[6]->IsDesignatorRange = 0
345pp_data->cap[6]->Reserved1 = 0x000000
346pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
347pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
348pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
349pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
350pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
351pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
352pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
353pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
354pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
355pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
356pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
357pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
358pp_data->cap[6]->NotRange.Usage = 0x0000
359pp_data->cap[6]->NotRange.Reserved1 = 0x0000
360pp_data->cap[6]->NotRange.StringIndex = 0
361pp_data->cap[6]->NotRange.Reserved2 = 0
362pp_data->cap[6]->NotRange.DesignatorIndex = 0
363pp_data->cap[6]->NotRange.Reserved3 = 0
364pp_data->cap[6]->NotRange.DataIndex = 1
365pp_data->cap[6]->NotRange.Reserved4 = 1
366pp_data->cap[6]->NotButton.HasNull = 0
367pp_data->cap[6]->NotButton.Reserved4 = 0x000000
368pp_data->cap[6]->NotButton.LogicalMin = 0
369pp_data->cap[6]->NotButton.LogicalMax = 1
370pp_data->cap[6]->NotButton.PhysicalMin = 0
371pp_data->cap[6]->NotButton.PhysicalMax = 0
372pp_data->cap[6]->Units = 0
373pp_data->cap[6]->UnitsExp = 0
374
375# Feature hid_pp_cap struct:
376# Link Collections:
377pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
378pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
379pp_data->LinkCollectionArray[0]->Parent = 0
380pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
381pp_data->LinkCollectionArray[0]->NextSibling = 0
382pp_data->LinkCollectionArray[0]->FirstChild = 0
383pp_data->LinkCollectionArray[0]->CollectionType = 1
384pp_data->LinkCollectionArray[0]->IsAlias = 0
385pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_expected.rpt_desc
new file mode 100644
index 0000000..d7ca045
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_expected.rpt_desc
@@ -0,0 +1,10 @@
10x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x01, 0x09, 0xE9,
20x09, 0xEA, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x02,
30x81, 0x06, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x85, 0x02,
40x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x10,
50x81, 0x02, 0x85, 0x05, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01,
60x75, 0x08, 0x95, 0x20, 0x81, 0x02, 0x85, 0x07, 0x09, 0x00,
70x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x81, 0x02,
80x85, 0x04, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08,
90x95, 0x24, 0x91, 0x02, 0x85, 0x06, 0x09, 0x00, 0x15, 0x00,
100x25, 0x01, 0x75, 0x08, 0x95, 0x24, 0x91, 0x02, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_real.rpt_desc
new file mode 100644
index 0000000..ba0fc3a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0001_000C_real.rpt_desc
@@ -0,0 +1,47 @@
1macOS USB Prober about 0x047F/0xC056 "Plantronics Blackwire 3220 Series"
205 0C 09 01 A1 01 85 01 15 00 25 01 09 E9 09 EA
375 01 95 02 81 06 95 06 81 01 85 02 05 0C 09 00
495 10 81 02 85 04 09 00 75 08 95 24 91 02 85 05
509 00 95 20 81 02 85 06 09 00 95 24 91 02 85 07
609 00 95 20 81 02 C0
7
8# Parser output:
9
100x05, 0x0C, // Usage Page (Consumer)
110x09, 0x01, // Usage (Consumer Control)
120xA1, 0x01, // Collection (Application)
130x85, 0x01, // Report ID (1)
140x15, 0x00, // Logical Minimum (0)
150x25, 0x01, // Logical Maximum (1)
160x09, 0xE9, // Usage (Volume Increment)
170x09, 0xEA, // Usage (Volume Decrement)
180x75, 0x01, // Report Size (1)
190x95, 0x02, // Report Count (2)
200x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
210x95, 0x06, // Report Count (6)
220x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
230x85, 0x02, // Report ID (2)
240x05, 0x0C, // Usage Page (Consumer)
250x09, 0x00, // Usage (Unassigned)
260x95, 0x10, // Report Count (16)
270x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
280x85, 0x04, // Report ID (4)
290x09, 0x00, // Usage (Unassigned)
300x75, 0x08, // Report Size (8)
310x95, 0x24, // Report Count (36)
320x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
330x85, 0x05, // Report ID (5)
340x09, 0x00, // Usage (Unassigned)
350x95, 0x20, // Report Count (32)
360x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
370x85, 0x06, // Report ID (6)
380x09, 0x00, // Usage (Unassigned)
390x95, 0x24, // Report Count (36)
400x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
410x85, 0x07, // Report ID (7)
420x09, 0x00, // Usage (Unassigned)
430x95, 0x20, // Report Count (32)
440x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
450xC0, // End Collection
46
47// 71 bytes
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0.pp_data
new file mode 100644
index 0000000..6def736
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0.pp_data
@@ -0,0 +1,1255 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x047F
3dev->product_id = 0xC056
4dev->manufacturer_string = "Plantronics"
5dev->product_string = "Plantronics Blackwire 3220 Series"
6dev->release_number = 0x0210
7dev->interface_number = 3
8dev->usage = 0x0003
9dev->usage_page = 0xFFA0
10dev->path = "\\?\hid#vid_047f&pid_c056&mi_03&col03#f&39e6f119&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0003
15pp_data->UsagePage = 0xFFA0
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 8
20pp_data->caps_info[0]->NumberOfCaps = 8
21pp_data->caps_info[0]->ReportByteLength = 33
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 8
24pp_data->caps_info[1]->LastCap = 16
25pp_data->caps_info[1]->NumberOfCaps = 8
26pp_data->caps_info[1]->ReportByteLength = 33
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 16
29pp_data->caps_info[2]->LastCap = 26
30pp_data->caps_info[2]->NumberOfCaps = 10
31pp_data->caps_info[2]->ReportByteLength = 3
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x0A90
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFFA0
37pp_data->cap[0]->ReportID = 0x03
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 8
40pp_data->cap[0]->ReportCount = 32
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 256
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0021
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0xFFA0
47pp_data->cap[0]->LinkUsage = 0x0003
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 0
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0030
70pp_data->cap[0]->NotRange.Reserved1 = 0x0030
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->NotButton.HasNull = 0
78pp_data->cap[0]->NotButton.Reserved4 = 0x000000
79pp_data->cap[0]->NotButton.LogicalMin = 0
80pp_data->cap[0]->NotButton.LogicalMax = 1
81pp_data->cap[0]->NotButton.PhysicalMin = 0
82pp_data->cap[0]->NotButton.PhysicalMax = 0
83pp_data->cap[0]->Units = 0
84pp_data->cap[0]->UnitsExp = 0
85
86pp_data->cap[1]->UsagePage = 0xFFA0
87pp_data->cap[1]->ReportID = 0x14
88pp_data->cap[1]->BitPosition = 4
89pp_data->cap[1]->BitSize = 1
90pp_data->cap[1]->ReportCount = 1
91pp_data->cap[1]->BytePosition = 0x0001
92pp_data->cap[1]->BitCount = 1
93pp_data->cap[1]->BitField = 0x06
94pp_data->cap[1]->NextBytePosition = 0x0002
95pp_data->cap[1]->LinkCollection = 0x0000
96pp_data->cap[1]->LinkUsagePage = 0xFFA0
97pp_data->cap[1]->LinkUsage = 0x0003
98pp_data->cap[1]->IsMultipleItemsForArray = 0
99pp_data->cap[1]->IsButtonCap = 1
100pp_data->cap[1]->IsPadding = 0
101pp_data->cap[1]->IsAbsolute = 0
102pp_data->cap[1]->IsRange = 0
103pp_data->cap[1]->IsAlias = 0
104pp_data->cap[1]->IsStringRange = 0
105pp_data->cap[1]->IsDesignatorRange = 0
106pp_data->cap[1]->Reserved1 = 0x000000
107pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
116pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
117pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
118pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
119pp_data->cap[1]->NotRange.Usage = 0x00B3
120pp_data->cap[1]->NotRange.Reserved1 = 0x00B3
121pp_data->cap[1]->NotRange.StringIndex = 0
122pp_data->cap[1]->NotRange.Reserved2 = 0
123pp_data->cap[1]->NotRange.DesignatorIndex = 0
124pp_data->cap[1]->NotRange.Reserved3 = 0
125pp_data->cap[1]->NotRange.DataIndex = 1
126pp_data->cap[1]->NotRange.Reserved4 = 1
127pp_data->cap[1]->Button.LogicalMin = 0
128pp_data->cap[1]->Button.LogicalMax = 0
129pp_data->cap[1]->Units = 0
130pp_data->cap[1]->UnitsExp = 0
131
132pp_data->cap[2]->UsagePage = 0xFFA0
133pp_data->cap[2]->ReportID = 0x14
134pp_data->cap[2]->BitPosition = 3
135pp_data->cap[2]->BitSize = 1
136pp_data->cap[2]->ReportCount = 1
137pp_data->cap[2]->BytePosition = 0x0001
138pp_data->cap[2]->BitCount = 1
139pp_data->cap[2]->BitField = 0x06
140pp_data->cap[2]->NextBytePosition = 0x0002
141pp_data->cap[2]->LinkCollection = 0x0000
142pp_data->cap[2]->LinkUsagePage = 0xFFA0
143pp_data->cap[2]->LinkUsage = 0x0003
144pp_data->cap[2]->IsMultipleItemsForArray = 0
145pp_data->cap[2]->IsButtonCap = 1
146pp_data->cap[2]->IsPadding = 0
147pp_data->cap[2]->IsAbsolute = 0
148pp_data->cap[2]->IsRange = 0
149pp_data->cap[2]->IsAlias = 0
150pp_data->cap[2]->IsStringRange = 0
151pp_data->cap[2]->IsDesignatorRange = 0
152pp_data->cap[2]->Reserved1 = 0x000000
153pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
154pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
155pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
156pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
157pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
158pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
159pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
160pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
161pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
162pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
163pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
164pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
165pp_data->cap[2]->NotRange.Usage = 0x00B7
166pp_data->cap[2]->NotRange.Reserved1 = 0x00B7
167pp_data->cap[2]->NotRange.StringIndex = 0
168pp_data->cap[2]->NotRange.Reserved2 = 0
169pp_data->cap[2]->NotRange.DesignatorIndex = 0
170pp_data->cap[2]->NotRange.Reserved3 = 0
171pp_data->cap[2]->NotRange.DataIndex = 2
172pp_data->cap[2]->NotRange.Reserved4 = 2
173pp_data->cap[2]->Button.LogicalMin = 0
174pp_data->cap[2]->Button.LogicalMax = 0
175pp_data->cap[2]->Units = 0
176pp_data->cap[2]->UnitsExp = 0
177
178pp_data->cap[3]->UsagePage = 0xFFA0
179pp_data->cap[3]->ReportID = 0x14
180pp_data->cap[3]->BitPosition = 2
181pp_data->cap[3]->BitSize = 1
182pp_data->cap[3]->ReportCount = 1
183pp_data->cap[3]->BytePosition = 0x0001
184pp_data->cap[3]->BitCount = 1
185pp_data->cap[3]->BitField = 0x06
186pp_data->cap[3]->NextBytePosition = 0x0002
187pp_data->cap[3]->LinkCollection = 0x0000
188pp_data->cap[3]->LinkUsagePage = 0xFFA0
189pp_data->cap[3]->LinkUsage = 0x0003
190pp_data->cap[3]->IsMultipleItemsForArray = 0
191pp_data->cap[3]->IsButtonCap = 1
192pp_data->cap[3]->IsPadding = 0
193pp_data->cap[3]->IsAbsolute = 0
194pp_data->cap[3]->IsRange = 0
195pp_data->cap[3]->IsAlias = 0
196pp_data->cap[3]->IsStringRange = 0
197pp_data->cap[3]->IsDesignatorRange = 0
198pp_data->cap[3]->Reserved1 = 0x000000
199pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
200pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
201pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
202pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
203pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
204pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
205pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
206pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
207pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
208pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
209pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
210pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
211pp_data->cap[3]->NotRange.Usage = 0x00B5
212pp_data->cap[3]->NotRange.Reserved1 = 0x00B5
213pp_data->cap[3]->NotRange.StringIndex = 0
214pp_data->cap[3]->NotRange.Reserved2 = 0
215pp_data->cap[3]->NotRange.DesignatorIndex = 0
216pp_data->cap[3]->NotRange.Reserved3 = 0
217pp_data->cap[3]->NotRange.DataIndex = 3
218pp_data->cap[3]->NotRange.Reserved4 = 3
219pp_data->cap[3]->Button.LogicalMin = 0
220pp_data->cap[3]->Button.LogicalMax = 0
221pp_data->cap[3]->Units = 0
222pp_data->cap[3]->UnitsExp = 0
223
224pp_data->cap[4]->UsagePage = 0xFFA0
225pp_data->cap[4]->ReportID = 0x14
226pp_data->cap[4]->BitPosition = 1
227pp_data->cap[4]->BitSize = 1
228pp_data->cap[4]->ReportCount = 1
229pp_data->cap[4]->BytePosition = 0x0001
230pp_data->cap[4]->BitCount = 1
231pp_data->cap[4]->BitField = 0x06
232pp_data->cap[4]->NextBytePosition = 0x0002
233pp_data->cap[4]->LinkCollection = 0x0000
234pp_data->cap[4]->LinkUsagePage = 0xFFA0
235pp_data->cap[4]->LinkUsage = 0x0003
236pp_data->cap[4]->IsMultipleItemsForArray = 0
237pp_data->cap[4]->IsButtonCap = 1
238pp_data->cap[4]->IsPadding = 0
239pp_data->cap[4]->IsAbsolute = 0
240pp_data->cap[4]->IsRange = 0
241pp_data->cap[4]->IsAlias = 0
242pp_data->cap[4]->IsStringRange = 0
243pp_data->cap[4]->IsDesignatorRange = 0
244pp_data->cap[4]->Reserved1 = 0x000000
245pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
246pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
247pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
248pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
249pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
250pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
251pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
252pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
253pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
254pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
255pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
256pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
257pp_data->cap[4]->NotRange.Usage = 0x00B2
258pp_data->cap[4]->NotRange.Reserved1 = 0x00B2
259pp_data->cap[4]->NotRange.StringIndex = 0
260pp_data->cap[4]->NotRange.Reserved2 = 0
261pp_data->cap[4]->NotRange.DesignatorIndex = 0
262pp_data->cap[4]->NotRange.Reserved3 = 0
263pp_data->cap[4]->NotRange.DataIndex = 4
264pp_data->cap[4]->NotRange.Reserved4 = 4
265pp_data->cap[4]->Button.LogicalMin = 0
266pp_data->cap[4]->Button.LogicalMax = 0
267pp_data->cap[4]->Units = 0
268pp_data->cap[4]->UnitsExp = 0
269
270pp_data->cap[5]->UsagePage = 0xFFA0
271pp_data->cap[5]->ReportID = 0x14
272pp_data->cap[5]->BitPosition = 0
273pp_data->cap[5]->BitSize = 1
274pp_data->cap[5]->ReportCount = 1
275pp_data->cap[5]->BytePosition = 0x0001
276pp_data->cap[5]->BitCount = 1
277pp_data->cap[5]->BitField = 0x06
278pp_data->cap[5]->NextBytePosition = 0x0002
279pp_data->cap[5]->LinkCollection = 0x0000
280pp_data->cap[5]->LinkUsagePage = 0xFFA0
281pp_data->cap[5]->LinkUsage = 0x0003
282pp_data->cap[5]->IsMultipleItemsForArray = 0
283pp_data->cap[5]->IsButtonCap = 1
284pp_data->cap[5]->IsPadding = 0
285pp_data->cap[5]->IsAbsolute = 0
286pp_data->cap[5]->IsRange = 0
287pp_data->cap[5]->IsAlias = 0
288pp_data->cap[5]->IsStringRange = 0
289pp_data->cap[5]->IsDesignatorRange = 0
290pp_data->cap[5]->Reserved1 = 0x000000
291pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
292pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
293pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
294pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
295pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
296pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
297pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
298pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
299pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
300pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
301pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
302pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
303pp_data->cap[5]->NotRange.Usage = 0x00B1
304pp_data->cap[5]->NotRange.Reserved1 = 0x00B1
305pp_data->cap[5]->NotRange.StringIndex = 0
306pp_data->cap[5]->NotRange.Reserved2 = 0
307pp_data->cap[5]->NotRange.DesignatorIndex = 0
308pp_data->cap[5]->NotRange.Reserved3 = 0
309pp_data->cap[5]->NotRange.DataIndex = 5
310pp_data->cap[5]->NotRange.Reserved4 = 5
311pp_data->cap[5]->Button.LogicalMin = 0
312pp_data->cap[5]->Button.LogicalMax = 0
313pp_data->cap[5]->Units = 0
314pp_data->cap[5]->UnitsExp = 0
315
316pp_data->cap[6]->UsagePage = 0xFFA0
317pp_data->cap[6]->ReportID = 0x15
318pp_data->cap[6]->BitPosition = 0
319pp_data->cap[6]->BitSize = 16
320pp_data->cap[6]->ReportCount = 1
321pp_data->cap[6]->BytePosition = 0x0001
322pp_data->cap[6]->BitCount = 16
323pp_data->cap[6]->BitField = 0x22
324pp_data->cap[6]->NextBytePosition = 0x0003
325pp_data->cap[6]->LinkCollection = 0x0000
326pp_data->cap[6]->LinkUsagePage = 0xFFA0
327pp_data->cap[6]->LinkUsage = 0x0003
328pp_data->cap[6]->IsMultipleItemsForArray = 0
329pp_data->cap[6]->IsButtonCap = 0
330pp_data->cap[6]->IsPadding = 0
331pp_data->cap[6]->IsAbsolute = 1
332pp_data->cap[6]->IsRange = 0
333pp_data->cap[6]->IsAlias = 0
334pp_data->cap[6]->IsStringRange = 0
335pp_data->cap[6]->IsDesignatorRange = 0
336pp_data->cap[6]->Reserved1 = 0x000000
337pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
338pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
339pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
340pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
341pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
342pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
343pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
344pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
345pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
346pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
347pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
348pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
349pp_data->cap[6]->NotRange.Usage = 0x008C
350pp_data->cap[6]->NotRange.Reserved1 = 0x008C
351pp_data->cap[6]->NotRange.StringIndex = 0
352pp_data->cap[6]->NotRange.Reserved2 = 0
353pp_data->cap[6]->NotRange.DesignatorIndex = 0
354pp_data->cap[6]->NotRange.Reserved3 = 0
355pp_data->cap[6]->NotRange.DataIndex = 6
356pp_data->cap[6]->NotRange.Reserved4 = 6
357pp_data->cap[6]->NotButton.HasNull = 0
358pp_data->cap[6]->NotButton.Reserved4 = 0x000000
359pp_data->cap[6]->NotButton.LogicalMin = 0
360pp_data->cap[6]->NotButton.LogicalMax = 65535
361pp_data->cap[6]->NotButton.PhysicalMin = 0
362pp_data->cap[6]->NotButton.PhysicalMax = 0
363pp_data->cap[6]->Units = 0
364pp_data->cap[6]->UnitsExp = 0
365
366pp_data->cap[7]->UsagePage = 0xFFA0
367pp_data->cap[7]->ReportID = 0x1F
368pp_data->cap[7]->BitPosition = 0
369pp_data->cap[7]->BitSize = 1
370pp_data->cap[7]->ReportCount = 1
371pp_data->cap[7]->BytePosition = 0x0001
372pp_data->cap[7]->BitCount = 1
373pp_data->cap[7]->BitField = 0x06
374pp_data->cap[7]->NextBytePosition = 0x0002
375pp_data->cap[7]->LinkCollection = 0x0000
376pp_data->cap[7]->LinkUsagePage = 0xFFA0
377pp_data->cap[7]->LinkUsage = 0x0003
378pp_data->cap[7]->IsMultipleItemsForArray = 0
379pp_data->cap[7]->IsButtonCap = 1
380pp_data->cap[7]->IsPadding = 0
381pp_data->cap[7]->IsAbsolute = 0
382pp_data->cap[7]->IsRange = 0
383pp_data->cap[7]->IsAlias = 0
384pp_data->cap[7]->IsStringRange = 0
385pp_data->cap[7]->IsDesignatorRange = 0
386pp_data->cap[7]->Reserved1 = 0x000000
387pp_data->cap[7]->pp_cap->UnknownTokens[0].Token = 0x00
388pp_data->cap[7]->pp_cap->UnknownTokens[0].Reserved = 0x000000
389pp_data->cap[7]->pp_cap->UnknownTokens[0].BitField = 0x00000000
390pp_data->cap[7]->pp_cap->UnknownTokens[1].Token = 0x00
391pp_data->cap[7]->pp_cap->UnknownTokens[1].Reserved = 0x000000
392pp_data->cap[7]->pp_cap->UnknownTokens[1].BitField = 0x00000000
393pp_data->cap[7]->pp_cap->UnknownTokens[2].Token = 0x00
394pp_data->cap[7]->pp_cap->UnknownTokens[2].Reserved = 0x000000
395pp_data->cap[7]->pp_cap->UnknownTokens[2].BitField = 0x00000000
396pp_data->cap[7]->pp_cap->UnknownTokens[3].Token = 0x00
397pp_data->cap[7]->pp_cap->UnknownTokens[3].Reserved = 0x000000
398pp_data->cap[7]->pp_cap->UnknownTokens[3].BitField = 0x00000000
399pp_data->cap[7]->NotRange.Usage = 0x009C
400pp_data->cap[7]->NotRange.Reserved1 = 0x009C
401pp_data->cap[7]->NotRange.StringIndex = 0
402pp_data->cap[7]->NotRange.Reserved2 = 0
403pp_data->cap[7]->NotRange.DesignatorIndex = 0
404pp_data->cap[7]->NotRange.Reserved3 = 0
405pp_data->cap[7]->NotRange.DataIndex = 7
406pp_data->cap[7]->NotRange.Reserved4 = 7
407pp_data->cap[7]->Button.LogicalMin = 0
408pp_data->cap[7]->Button.LogicalMax = 0
409pp_data->cap[7]->Units = 0
410pp_data->cap[7]->UnitsExp = 0
411
412# Output hid_pp_cap struct:
413pp_data->cap[8]->UsagePage = 0xFFA0
414pp_data->cap[8]->ReportID = 0x03
415pp_data->cap[8]->BitPosition = 0
416pp_data->cap[8]->BitSize = 8
417pp_data->cap[8]->ReportCount = 32
418pp_data->cap[8]->BytePosition = 0x0001
419pp_data->cap[8]->BitCount = 256
420pp_data->cap[8]->BitField = 0x02
421pp_data->cap[8]->NextBytePosition = 0x0021
422pp_data->cap[8]->LinkCollection = 0x0000
423pp_data->cap[8]->LinkUsagePage = 0xFFA0
424pp_data->cap[8]->LinkUsage = 0x0003
425pp_data->cap[8]->IsMultipleItemsForArray = 0
426pp_data->cap[8]->IsButtonCap = 0
427pp_data->cap[8]->IsPadding = 0
428pp_data->cap[8]->IsAbsolute = 1
429pp_data->cap[8]->IsRange = 0
430pp_data->cap[8]->IsAlias = 0
431pp_data->cap[8]->IsStringRange = 0
432pp_data->cap[8]->IsDesignatorRange = 0
433pp_data->cap[8]->Reserved1 = 0x000000
434pp_data->cap[8]->pp_cap->UnknownTokens[0].Token = 0x00
435pp_data->cap[8]->pp_cap->UnknownTokens[0].Reserved = 0x000000
436pp_data->cap[8]->pp_cap->UnknownTokens[0].BitField = 0x00000000
437pp_data->cap[8]->pp_cap->UnknownTokens[1].Token = 0x00
438pp_data->cap[8]->pp_cap->UnknownTokens[1].Reserved = 0x000000
439pp_data->cap[8]->pp_cap->UnknownTokens[1].BitField = 0x00000000
440pp_data->cap[8]->pp_cap->UnknownTokens[2].Token = 0x00
441pp_data->cap[8]->pp_cap->UnknownTokens[2].Reserved = 0x000000
442pp_data->cap[8]->pp_cap->UnknownTokens[2].BitField = 0x00000000
443pp_data->cap[8]->pp_cap->UnknownTokens[3].Token = 0x00
444pp_data->cap[8]->pp_cap->UnknownTokens[3].Reserved = 0x000000
445pp_data->cap[8]->pp_cap->UnknownTokens[3].BitField = 0x00000000
446pp_data->cap[8]->NotRange.Usage = 0x0030
447pp_data->cap[8]->NotRange.Reserved1 = 0x0030
448pp_data->cap[8]->NotRange.StringIndex = 0
449pp_data->cap[8]->NotRange.Reserved2 = 0
450pp_data->cap[8]->NotRange.DesignatorIndex = 0
451pp_data->cap[8]->NotRange.Reserved3 = 0
452pp_data->cap[8]->NotRange.DataIndex = 0
453pp_data->cap[8]->NotRange.Reserved4 = 0
454pp_data->cap[8]->NotButton.HasNull = 0
455pp_data->cap[8]->NotButton.Reserved4 = 0x000000
456pp_data->cap[8]->NotButton.LogicalMin = 0
457pp_data->cap[8]->NotButton.LogicalMax = 1
458pp_data->cap[8]->NotButton.PhysicalMin = 0
459pp_data->cap[8]->NotButton.PhysicalMax = 0
460pp_data->cap[8]->Units = 0
461pp_data->cap[8]->UnitsExp = 0
462
463pp_data->cap[9]->UsagePage = 0xFFA0
464pp_data->cap[9]->ReportID = 0x19
465pp_data->cap[9]->BitPosition = 3
466pp_data->cap[9]->BitSize = 1
467pp_data->cap[9]->ReportCount = 1
468pp_data->cap[9]->BytePosition = 0x0001
469pp_data->cap[9]->BitCount = 1
470pp_data->cap[9]->BitField = 0x22
471pp_data->cap[9]->NextBytePosition = 0x0002
472pp_data->cap[9]->LinkCollection = 0x0000
473pp_data->cap[9]->LinkUsagePage = 0xFFA0
474pp_data->cap[9]->LinkUsage = 0x0003
475pp_data->cap[9]->IsMultipleItemsForArray = 0
476pp_data->cap[9]->IsButtonCap = 1
477pp_data->cap[9]->IsPadding = 0
478pp_data->cap[9]->IsAbsolute = 1
479pp_data->cap[9]->IsRange = 0
480pp_data->cap[9]->IsAlias = 0
481pp_data->cap[9]->IsStringRange = 0
482pp_data->cap[9]->IsDesignatorRange = 0
483pp_data->cap[9]->Reserved1 = 0x000000
484pp_data->cap[9]->pp_cap->UnknownTokens[0].Token = 0x00
485pp_data->cap[9]->pp_cap->UnknownTokens[0].Reserved = 0x000000
486pp_data->cap[9]->pp_cap->UnknownTokens[0].BitField = 0x00000000
487pp_data->cap[9]->pp_cap->UnknownTokens[1].Token = 0x00
488pp_data->cap[9]->pp_cap->UnknownTokens[1].Reserved = 0x000000
489pp_data->cap[9]->pp_cap->UnknownTokens[1].BitField = 0x00000000
490pp_data->cap[9]->pp_cap->UnknownTokens[2].Token = 0x00
491pp_data->cap[9]->pp_cap->UnknownTokens[2].Reserved = 0x000000
492pp_data->cap[9]->pp_cap->UnknownTokens[2].BitField = 0x00000000
493pp_data->cap[9]->pp_cap->UnknownTokens[3].Token = 0x00
494pp_data->cap[9]->pp_cap->UnknownTokens[3].Reserved = 0x000000
495pp_data->cap[9]->pp_cap->UnknownTokens[3].BitField = 0x00000000
496pp_data->cap[9]->NotRange.Usage = 0x00DC
497pp_data->cap[9]->NotRange.Reserved1 = 0x00DC
498pp_data->cap[9]->NotRange.StringIndex = 0
499pp_data->cap[9]->NotRange.Reserved2 = 0
500pp_data->cap[9]->NotRange.DesignatorIndex = 0
501pp_data->cap[9]->NotRange.Reserved3 = 0
502pp_data->cap[9]->NotRange.DataIndex = 1
503pp_data->cap[9]->NotRange.Reserved4 = 1
504pp_data->cap[9]->Button.LogicalMin = 0
505pp_data->cap[9]->Button.LogicalMax = 0
506pp_data->cap[9]->Units = 0
507pp_data->cap[9]->UnitsExp = 0
508
509pp_data->cap[10]->UsagePage = 0xFFA0
510pp_data->cap[10]->ReportID = 0x19
511pp_data->cap[10]->BitPosition = 2
512pp_data->cap[10]->BitSize = 1
513pp_data->cap[10]->ReportCount = 1
514pp_data->cap[10]->BytePosition = 0x0001
515pp_data->cap[10]->BitCount = 1
516pp_data->cap[10]->BitField = 0x22
517pp_data->cap[10]->NextBytePosition = 0x0002
518pp_data->cap[10]->LinkCollection = 0x0000
519pp_data->cap[10]->LinkUsagePage = 0xFFA0
520pp_data->cap[10]->LinkUsage = 0x0003
521pp_data->cap[10]->IsMultipleItemsForArray = 0
522pp_data->cap[10]->IsButtonCap = 1
523pp_data->cap[10]->IsPadding = 0
524pp_data->cap[10]->IsAbsolute = 1
525pp_data->cap[10]->IsRange = 0
526pp_data->cap[10]->IsAlias = 0
527pp_data->cap[10]->IsStringRange = 0
528pp_data->cap[10]->IsDesignatorRange = 0
529pp_data->cap[10]->Reserved1 = 0x000000
530pp_data->cap[10]->pp_cap->UnknownTokens[0].Token = 0x00
531pp_data->cap[10]->pp_cap->UnknownTokens[0].Reserved = 0x000000
532pp_data->cap[10]->pp_cap->UnknownTokens[0].BitField = 0x00000000
533pp_data->cap[10]->pp_cap->UnknownTokens[1].Token = 0x00
534pp_data->cap[10]->pp_cap->UnknownTokens[1].Reserved = 0x000000
535pp_data->cap[10]->pp_cap->UnknownTokens[1].BitField = 0x00000000
536pp_data->cap[10]->pp_cap->UnknownTokens[2].Token = 0x00
537pp_data->cap[10]->pp_cap->UnknownTokens[2].Reserved = 0x000000
538pp_data->cap[10]->pp_cap->UnknownTokens[2].BitField = 0x00000000
539pp_data->cap[10]->pp_cap->UnknownTokens[3].Token = 0x00
540pp_data->cap[10]->pp_cap->UnknownTokens[3].Reserved = 0x000000
541pp_data->cap[10]->pp_cap->UnknownTokens[3].BitField = 0x00000000
542pp_data->cap[10]->NotRange.Usage = 0x009E
543pp_data->cap[10]->NotRange.Reserved1 = 0x009E
544pp_data->cap[10]->NotRange.StringIndex = 0
545pp_data->cap[10]->NotRange.Reserved2 = 0
546pp_data->cap[10]->NotRange.DesignatorIndex = 0
547pp_data->cap[10]->NotRange.Reserved3 = 0
548pp_data->cap[10]->NotRange.DataIndex = 2
549pp_data->cap[10]->NotRange.Reserved4 = 2
550pp_data->cap[10]->Button.LogicalMin = 0
551pp_data->cap[10]->Button.LogicalMax = 0
552pp_data->cap[10]->Units = 0
553pp_data->cap[10]->UnitsExp = 0
554
555pp_data->cap[11]->UsagePage = 0xFFA0
556pp_data->cap[11]->ReportID = 0x19
557pp_data->cap[11]->BitPosition = 1
558pp_data->cap[11]->BitSize = 1
559pp_data->cap[11]->ReportCount = 1
560pp_data->cap[11]->BytePosition = 0x0001
561pp_data->cap[11]->BitCount = 1
562pp_data->cap[11]->BitField = 0x22
563pp_data->cap[11]->NextBytePosition = 0x0002
564pp_data->cap[11]->LinkCollection = 0x0000
565pp_data->cap[11]->LinkUsagePage = 0xFFA0
566pp_data->cap[11]->LinkUsage = 0x0003
567pp_data->cap[11]->IsMultipleItemsForArray = 0
568pp_data->cap[11]->IsButtonCap = 1
569pp_data->cap[11]->IsPadding = 0
570pp_data->cap[11]->IsAbsolute = 1
571pp_data->cap[11]->IsRange = 0
572pp_data->cap[11]->IsAlias = 0
573pp_data->cap[11]->IsStringRange = 0
574pp_data->cap[11]->IsDesignatorRange = 0
575pp_data->cap[11]->Reserved1 = 0x000000
576pp_data->cap[11]->pp_cap->UnknownTokens[0].Token = 0x00
577pp_data->cap[11]->pp_cap->UnknownTokens[0].Reserved = 0x000000
578pp_data->cap[11]->pp_cap->UnknownTokens[0].BitField = 0x00000000
579pp_data->cap[11]->pp_cap->UnknownTokens[1].Token = 0x00
580pp_data->cap[11]->pp_cap->UnknownTokens[1].Reserved = 0x000000
581pp_data->cap[11]->pp_cap->UnknownTokens[1].BitField = 0x00000000
582pp_data->cap[11]->pp_cap->UnknownTokens[2].Token = 0x00
583pp_data->cap[11]->pp_cap->UnknownTokens[2].Reserved = 0x000000
584pp_data->cap[11]->pp_cap->UnknownTokens[2].BitField = 0x00000000
585pp_data->cap[11]->pp_cap->UnknownTokens[3].Token = 0x00
586pp_data->cap[11]->pp_cap->UnknownTokens[3].Reserved = 0x000000
587pp_data->cap[11]->pp_cap->UnknownTokens[3].BitField = 0x00000000
588pp_data->cap[11]->NotRange.Usage = 0x008F
589pp_data->cap[11]->NotRange.Reserved1 = 0x008F
590pp_data->cap[11]->NotRange.StringIndex = 0
591pp_data->cap[11]->NotRange.Reserved2 = 0
592pp_data->cap[11]->NotRange.DesignatorIndex = 0
593pp_data->cap[11]->NotRange.Reserved3 = 0
594pp_data->cap[11]->NotRange.DataIndex = 3
595pp_data->cap[11]->NotRange.Reserved4 = 3
596pp_data->cap[11]->Button.LogicalMin = 0
597pp_data->cap[11]->Button.LogicalMax = 0
598pp_data->cap[11]->Units = 0
599pp_data->cap[11]->UnitsExp = 0
600
601pp_data->cap[12]->UsagePage = 0xFFA0
602pp_data->cap[12]->ReportID = 0x19
603pp_data->cap[12]->BitPosition = 0
604pp_data->cap[12]->BitSize = 1
605pp_data->cap[12]->ReportCount = 1
606pp_data->cap[12]->BytePosition = 0x0001
607pp_data->cap[12]->BitCount = 1
608pp_data->cap[12]->BitField = 0x22
609pp_data->cap[12]->NextBytePosition = 0x0002
610pp_data->cap[12]->LinkCollection = 0x0000
611pp_data->cap[12]->LinkUsagePage = 0xFFA0
612pp_data->cap[12]->LinkUsage = 0x0003
613pp_data->cap[12]->IsMultipleItemsForArray = 0
614pp_data->cap[12]->IsButtonCap = 1
615pp_data->cap[12]->IsPadding = 0
616pp_data->cap[12]->IsAbsolute = 1
617pp_data->cap[12]->IsRange = 0
618pp_data->cap[12]->IsAlias = 0
619pp_data->cap[12]->IsStringRange = 0
620pp_data->cap[12]->IsDesignatorRange = 0
621pp_data->cap[12]->Reserved1 = 0x000000
622pp_data->cap[12]->pp_cap->UnknownTokens[0].Token = 0x00
623pp_data->cap[12]->pp_cap->UnknownTokens[0].Reserved = 0x000000
624pp_data->cap[12]->pp_cap->UnknownTokens[0].BitField = 0x00000000
625pp_data->cap[12]->pp_cap->UnknownTokens[1].Token = 0x00
626pp_data->cap[12]->pp_cap->UnknownTokens[1].Reserved = 0x000000
627pp_data->cap[12]->pp_cap->UnknownTokens[1].BitField = 0x00000000
628pp_data->cap[12]->pp_cap->UnknownTokens[2].Token = 0x00
629pp_data->cap[12]->pp_cap->UnknownTokens[2].Reserved = 0x000000
630pp_data->cap[12]->pp_cap->UnknownTokens[2].BitField = 0x00000000
631pp_data->cap[12]->pp_cap->UnknownTokens[3].Token = 0x00
632pp_data->cap[12]->pp_cap->UnknownTokens[3].Reserved = 0x000000
633pp_data->cap[12]->pp_cap->UnknownTokens[3].BitField = 0x00000000
634pp_data->cap[12]->NotRange.Usage = 0x008D
635pp_data->cap[12]->NotRange.Reserved1 = 0x008D
636pp_data->cap[12]->NotRange.StringIndex = 0
637pp_data->cap[12]->NotRange.Reserved2 = 0
638pp_data->cap[12]->NotRange.DesignatorIndex = 0
639pp_data->cap[12]->NotRange.Reserved3 = 0
640pp_data->cap[12]->NotRange.DataIndex = 4
641pp_data->cap[12]->NotRange.Reserved4 = 4
642pp_data->cap[12]->Button.LogicalMin = 0
643pp_data->cap[12]->Button.LogicalMax = 0
644pp_data->cap[12]->Units = 0
645pp_data->cap[12]->UnitsExp = 0
646
647pp_data->cap[13]->UsagePage = 0xFFA0
648pp_data->cap[13]->ReportID = 0x19
649pp_data->cap[13]->BitPosition = 5
650pp_data->cap[13]->BitSize = 1
651pp_data->cap[13]->ReportCount = 1
652pp_data->cap[13]->BytePosition = 0x0001
653pp_data->cap[13]->BitCount = 1
654pp_data->cap[13]->BitField = 0x06
655pp_data->cap[13]->NextBytePosition = 0x0002
656pp_data->cap[13]->LinkCollection = 0x0000
657pp_data->cap[13]->LinkUsagePage = 0xFFA0
658pp_data->cap[13]->LinkUsage = 0x0003
659pp_data->cap[13]->IsMultipleItemsForArray = 0
660pp_data->cap[13]->IsButtonCap = 1
661pp_data->cap[13]->IsPadding = 0
662pp_data->cap[13]->IsAbsolute = 0
663pp_data->cap[13]->IsRange = 0
664pp_data->cap[13]->IsAlias = 0
665pp_data->cap[13]->IsStringRange = 0
666pp_data->cap[13]->IsDesignatorRange = 0
667pp_data->cap[13]->Reserved1 = 0x000000
668pp_data->cap[13]->pp_cap->UnknownTokens[0].Token = 0x00
669pp_data->cap[13]->pp_cap->UnknownTokens[0].Reserved = 0x000000
670pp_data->cap[13]->pp_cap->UnknownTokens[0].BitField = 0x00000000
671pp_data->cap[13]->pp_cap->UnknownTokens[1].Token = 0x00
672pp_data->cap[13]->pp_cap->UnknownTokens[1].Reserved = 0x000000
673pp_data->cap[13]->pp_cap->UnknownTokens[1].BitField = 0x00000000
674pp_data->cap[13]->pp_cap->UnknownTokens[2].Token = 0x00
675pp_data->cap[13]->pp_cap->UnknownTokens[2].Reserved = 0x000000
676pp_data->cap[13]->pp_cap->UnknownTokens[2].BitField = 0x00000000
677pp_data->cap[13]->pp_cap->UnknownTokens[3].Token = 0x00
678pp_data->cap[13]->pp_cap->UnknownTokens[3].Reserved = 0x000000
679pp_data->cap[13]->pp_cap->UnknownTokens[3].BitField = 0x00000000
680pp_data->cap[13]->NotRange.Usage = 0x00D9
681pp_data->cap[13]->NotRange.Reserved1 = 0x00D9
682pp_data->cap[13]->NotRange.StringIndex = 0
683pp_data->cap[13]->NotRange.Reserved2 = 0
684pp_data->cap[13]->NotRange.DesignatorIndex = 0
685pp_data->cap[13]->NotRange.Reserved3 = 0
686pp_data->cap[13]->NotRange.DataIndex = 5
687pp_data->cap[13]->NotRange.Reserved4 = 5
688pp_data->cap[13]->Button.LogicalMin = 0
689pp_data->cap[13]->Button.LogicalMax = 0
690pp_data->cap[13]->Units = 0
691pp_data->cap[13]->UnitsExp = 0
692
693pp_data->cap[14]->UsagePage = 0xFFA0
694pp_data->cap[14]->ReportID = 0x19
695pp_data->cap[14]->BitPosition = 4
696pp_data->cap[14]->BitSize = 1
697pp_data->cap[14]->ReportCount = 1
698pp_data->cap[14]->BytePosition = 0x0001
699pp_data->cap[14]->BitCount = 1
700pp_data->cap[14]->BitField = 0x06
701pp_data->cap[14]->NextBytePosition = 0x0002
702pp_data->cap[14]->LinkCollection = 0x0000
703pp_data->cap[14]->LinkUsagePage = 0xFFA0
704pp_data->cap[14]->LinkUsage = 0x0003
705pp_data->cap[14]->IsMultipleItemsForArray = 0
706pp_data->cap[14]->IsButtonCap = 1
707pp_data->cap[14]->IsPadding = 0
708pp_data->cap[14]->IsAbsolute = 0
709pp_data->cap[14]->IsRange = 0
710pp_data->cap[14]->IsAlias = 0
711pp_data->cap[14]->IsStringRange = 0
712pp_data->cap[14]->IsDesignatorRange = 0
713pp_data->cap[14]->Reserved1 = 0x000000
714pp_data->cap[14]->pp_cap->UnknownTokens[0].Token = 0x00
715pp_data->cap[14]->pp_cap->UnknownTokens[0].Reserved = 0x000000
716pp_data->cap[14]->pp_cap->UnknownTokens[0].BitField = 0x00000000
717pp_data->cap[14]->pp_cap->UnknownTokens[1].Token = 0x00
718pp_data->cap[14]->pp_cap->UnknownTokens[1].Reserved = 0x000000
719pp_data->cap[14]->pp_cap->UnknownTokens[1].BitField = 0x00000000
720pp_data->cap[14]->pp_cap->UnknownTokens[2].Token = 0x00
721pp_data->cap[14]->pp_cap->UnknownTokens[2].Reserved = 0x000000
722pp_data->cap[14]->pp_cap->UnknownTokens[2].BitField = 0x00000000
723pp_data->cap[14]->pp_cap->UnknownTokens[3].Token = 0x00
724pp_data->cap[14]->pp_cap->UnknownTokens[3].Reserved = 0x000000
725pp_data->cap[14]->pp_cap->UnknownTokens[3].BitField = 0x00000000
726pp_data->cap[14]->NotRange.Usage = 0x00D2
727pp_data->cap[14]->NotRange.Reserved1 = 0x00D2
728pp_data->cap[14]->NotRange.StringIndex = 0
729pp_data->cap[14]->NotRange.Reserved2 = 0
730pp_data->cap[14]->NotRange.DesignatorIndex = 0
731pp_data->cap[14]->NotRange.Reserved3 = 0
732pp_data->cap[14]->NotRange.DataIndex = 6
733pp_data->cap[14]->NotRange.Reserved4 = 6
734pp_data->cap[14]->Button.LogicalMin = 0
735pp_data->cap[14]->Button.LogicalMax = 0
736pp_data->cap[14]->Units = 0
737pp_data->cap[14]->UnitsExp = 0
738
739pp_data->cap[15]->UsagePage = 0xFFA0
740pp_data->cap[15]->ReportID = 0x1A
741pp_data->cap[15]->BitPosition = 0
742pp_data->cap[15]->BitSize = 1
743pp_data->cap[15]->ReportCount = 1
744pp_data->cap[15]->BytePosition = 0x0001
745pp_data->cap[15]->BitCount = 1
746pp_data->cap[15]->BitField = 0x22
747pp_data->cap[15]->NextBytePosition = 0x0002
748pp_data->cap[15]->LinkCollection = 0x0000
749pp_data->cap[15]->LinkUsagePage = 0xFFA0
750pp_data->cap[15]->LinkUsage = 0x0003
751pp_data->cap[15]->IsMultipleItemsForArray = 0
752pp_data->cap[15]->IsButtonCap = 1
753pp_data->cap[15]->IsPadding = 0
754pp_data->cap[15]->IsAbsolute = 1
755pp_data->cap[15]->IsRange = 0
756pp_data->cap[15]->IsAlias = 0
757pp_data->cap[15]->IsStringRange = 0
758pp_data->cap[15]->IsDesignatorRange = 0
759pp_data->cap[15]->Reserved1 = 0x000000
760pp_data->cap[15]->pp_cap->UnknownTokens[0].Token = 0x00
761pp_data->cap[15]->pp_cap->UnknownTokens[0].Reserved = 0x000000
762pp_data->cap[15]->pp_cap->UnknownTokens[0].BitField = 0x00000000
763pp_data->cap[15]->pp_cap->UnknownTokens[1].Token = 0x00
764pp_data->cap[15]->pp_cap->UnknownTokens[1].Reserved = 0x000000
765pp_data->cap[15]->pp_cap->UnknownTokens[1].BitField = 0x00000000
766pp_data->cap[15]->pp_cap->UnknownTokens[2].Token = 0x00
767pp_data->cap[15]->pp_cap->UnknownTokens[2].Reserved = 0x000000
768pp_data->cap[15]->pp_cap->UnknownTokens[2].BitField = 0x00000000
769pp_data->cap[15]->pp_cap->UnknownTokens[3].Token = 0x00
770pp_data->cap[15]->pp_cap->UnknownTokens[3].Reserved = 0x000000
771pp_data->cap[15]->pp_cap->UnknownTokens[3].BitField = 0x00000000
772pp_data->cap[15]->NotRange.Usage = 0x00B5
773pp_data->cap[15]->NotRange.Reserved1 = 0x00B5
774pp_data->cap[15]->NotRange.StringIndex = 0
775pp_data->cap[15]->NotRange.Reserved2 = 0
776pp_data->cap[15]->NotRange.DesignatorIndex = 0
777pp_data->cap[15]->NotRange.Reserved3 = 0
778pp_data->cap[15]->NotRange.DataIndex = 7
779pp_data->cap[15]->NotRange.Reserved4 = 7
780pp_data->cap[15]->Button.LogicalMin = 0
781pp_data->cap[15]->Button.LogicalMax = 0
782pp_data->cap[15]->Units = 0
783pp_data->cap[15]->UnitsExp = 0
784
785# Feature hid_pp_cap struct:
786pp_data->cap[16]->UsagePage = 0xFFA0
787pp_data->cap[16]->ReportID = 0x1B
788pp_data->cap[16]->BitPosition = 1
789pp_data->cap[16]->BitSize = 1
790pp_data->cap[16]->ReportCount = 1
791pp_data->cap[16]->BytePosition = 0x0001
792pp_data->cap[16]->BitCount = 1
793pp_data->cap[16]->BitField = 0x22
794pp_data->cap[16]->NextBytePosition = 0x0002
795pp_data->cap[16]->LinkCollection = 0x0000
796pp_data->cap[16]->LinkUsagePage = 0xFFA0
797pp_data->cap[16]->LinkUsage = 0x0003
798pp_data->cap[16]->IsMultipleItemsForArray = 0
799pp_data->cap[16]->IsButtonCap = 1
800pp_data->cap[16]->IsPadding = 0
801pp_data->cap[16]->IsAbsolute = 1
802pp_data->cap[16]->IsRange = 0
803pp_data->cap[16]->IsAlias = 0
804pp_data->cap[16]->IsStringRange = 0
805pp_data->cap[16]->IsDesignatorRange = 0
806pp_data->cap[16]->Reserved1 = 0x000000
807pp_data->cap[16]->pp_cap->UnknownTokens[0].Token = 0x00
808pp_data->cap[16]->pp_cap->UnknownTokens[0].Reserved = 0x000000
809pp_data->cap[16]->pp_cap->UnknownTokens[0].BitField = 0x00000000
810pp_data->cap[16]->pp_cap->UnknownTokens[1].Token = 0x00
811pp_data->cap[16]->pp_cap->UnknownTokens[1].Reserved = 0x000000
812pp_data->cap[16]->pp_cap->UnknownTokens[1].BitField = 0x00000000
813pp_data->cap[16]->pp_cap->UnknownTokens[2].Token = 0x00
814pp_data->cap[16]->pp_cap->UnknownTokens[2].Reserved = 0x000000
815pp_data->cap[16]->pp_cap->UnknownTokens[2].BitField = 0x00000000
816pp_data->cap[16]->pp_cap->UnknownTokens[3].Token = 0x00
817pp_data->cap[16]->pp_cap->UnknownTokens[3].Reserved = 0x000000
818pp_data->cap[16]->pp_cap->UnknownTokens[3].BitField = 0x00000000
819pp_data->cap[16]->NotRange.Usage = 0x00B5
820pp_data->cap[16]->NotRange.Reserved1 = 0x00B5
821pp_data->cap[16]->NotRange.StringIndex = 0
822pp_data->cap[16]->NotRange.Reserved2 = 0
823pp_data->cap[16]->NotRange.DesignatorIndex = 0
824pp_data->cap[16]->NotRange.Reserved3 = 0
825pp_data->cap[16]->NotRange.DataIndex = 0
826pp_data->cap[16]->NotRange.Reserved4 = 0
827pp_data->cap[16]->Button.LogicalMin = 0
828pp_data->cap[16]->Button.LogicalMax = 0
829pp_data->cap[16]->Units = 0
830pp_data->cap[16]->UnitsExp = 0
831
832pp_data->cap[17]->UsagePage = 0xFFA0
833pp_data->cap[17]->ReportID = 0x1B
834pp_data->cap[17]->BitPosition = 0
835pp_data->cap[17]->BitSize = 1
836pp_data->cap[17]->ReportCount = 1
837pp_data->cap[17]->BytePosition = 0x0001
838pp_data->cap[17]->BitCount = 1
839pp_data->cap[17]->BitField = 0x22
840pp_data->cap[17]->NextBytePosition = 0x0002
841pp_data->cap[17]->LinkCollection = 0x0000
842pp_data->cap[17]->LinkUsagePage = 0xFFA0
843pp_data->cap[17]->LinkUsage = 0x0003
844pp_data->cap[17]->IsMultipleItemsForArray = 0
845pp_data->cap[17]->IsButtonCap = 1
846pp_data->cap[17]->IsPadding = 0
847pp_data->cap[17]->IsAbsolute = 1
848pp_data->cap[17]->IsRange = 0
849pp_data->cap[17]->IsAlias = 0
850pp_data->cap[17]->IsStringRange = 0
851pp_data->cap[17]->IsDesignatorRange = 0
852pp_data->cap[17]->Reserved1 = 0x000000
853pp_data->cap[17]->pp_cap->UnknownTokens[0].Token = 0x00
854pp_data->cap[17]->pp_cap->UnknownTokens[0].Reserved = 0x000000
855pp_data->cap[17]->pp_cap->UnknownTokens[0].BitField = 0x00000000
856pp_data->cap[17]->pp_cap->UnknownTokens[1].Token = 0x00
857pp_data->cap[17]->pp_cap->UnknownTokens[1].Reserved = 0x000000
858pp_data->cap[17]->pp_cap->UnknownTokens[1].BitField = 0x00000000
859pp_data->cap[17]->pp_cap->UnknownTokens[2].Token = 0x00
860pp_data->cap[17]->pp_cap->UnknownTokens[2].Reserved = 0x000000
861pp_data->cap[17]->pp_cap->UnknownTokens[2].BitField = 0x00000000
862pp_data->cap[17]->pp_cap->UnknownTokens[3].Token = 0x00
863pp_data->cap[17]->pp_cap->UnknownTokens[3].Reserved = 0x000000
864pp_data->cap[17]->pp_cap->UnknownTokens[3].BitField = 0x00000000
865pp_data->cap[17]->NotRange.Usage = 0x00CF
866pp_data->cap[17]->NotRange.Reserved1 = 0x00CF
867pp_data->cap[17]->NotRange.StringIndex = 0
868pp_data->cap[17]->NotRange.Reserved2 = 0
869pp_data->cap[17]->NotRange.DesignatorIndex = 0
870pp_data->cap[17]->NotRange.Reserved3 = 0
871pp_data->cap[17]->NotRange.DataIndex = 1
872pp_data->cap[17]->NotRange.Reserved4 = 1
873pp_data->cap[17]->Button.LogicalMin = 0
874pp_data->cap[17]->Button.LogicalMax = 0
875pp_data->cap[17]->Units = 0
876pp_data->cap[17]->UnitsExp = 0
877
878pp_data->cap[18]->UsagePage = 0xFFA0
879pp_data->cap[18]->ReportID = 0x1B
880pp_data->cap[18]->BitPosition = 2
881pp_data->cap[18]->BitSize = 1
882pp_data->cap[18]->ReportCount = 1
883pp_data->cap[18]->BytePosition = 0x0001
884pp_data->cap[18]->BitCount = 1
885pp_data->cap[18]->BitField = 0x23
886pp_data->cap[18]->NextBytePosition = 0x0002
887pp_data->cap[18]->LinkCollection = 0x0000
888pp_data->cap[18]->LinkUsagePage = 0xFFA0
889pp_data->cap[18]->LinkUsage = 0x0003
890pp_data->cap[18]->IsMultipleItemsForArray = 0
891pp_data->cap[18]->IsButtonCap = 1
892pp_data->cap[18]->IsPadding = 1
893pp_data->cap[18]->IsAbsolute = 1
894pp_data->cap[18]->IsRange = 0
895pp_data->cap[18]->IsAlias = 0
896pp_data->cap[18]->IsStringRange = 0
897pp_data->cap[18]->IsDesignatorRange = 0
898pp_data->cap[18]->Reserved1 = 0x000000
899pp_data->cap[18]->pp_cap->UnknownTokens[0].Token = 0x00
900pp_data->cap[18]->pp_cap->UnknownTokens[0].Reserved = 0x000000
901pp_data->cap[18]->pp_cap->UnknownTokens[0].BitField = 0x00000000
902pp_data->cap[18]->pp_cap->UnknownTokens[1].Token = 0x00
903pp_data->cap[18]->pp_cap->UnknownTokens[1].Reserved = 0x000000
904pp_data->cap[18]->pp_cap->UnknownTokens[1].BitField = 0x00000000
905pp_data->cap[18]->pp_cap->UnknownTokens[2].Token = 0x00
906pp_data->cap[18]->pp_cap->UnknownTokens[2].Reserved = 0x000000
907pp_data->cap[18]->pp_cap->UnknownTokens[2].BitField = 0x00000000
908pp_data->cap[18]->pp_cap->UnknownTokens[3].Token = 0x00
909pp_data->cap[18]->pp_cap->UnknownTokens[3].Reserved = 0x000000
910pp_data->cap[18]->pp_cap->UnknownTokens[3].BitField = 0x00000000
911pp_data->cap[18]->NotRange.Usage = 0x00DE
912pp_data->cap[18]->NotRange.Reserved1 = 0x00DE
913pp_data->cap[18]->NotRange.StringIndex = 0
914pp_data->cap[18]->NotRange.Reserved2 = 0
915pp_data->cap[18]->NotRange.DesignatorIndex = 0
916pp_data->cap[18]->NotRange.Reserved3 = 0
917pp_data->cap[18]->NotRange.DataIndex = 2
918pp_data->cap[18]->NotRange.Reserved4 = 2
919pp_data->cap[18]->Button.LogicalMin = 0
920pp_data->cap[18]->Button.LogicalMax = 0
921pp_data->cap[18]->Units = 0
922pp_data->cap[18]->UnitsExp = 0
923
924pp_data->cap[19]->UsagePage = 0xFFA0
925pp_data->cap[19]->ReportID = 0x1B
926pp_data->cap[19]->BitPosition = 3
927pp_data->cap[19]->BitSize = 1
928pp_data->cap[19]->ReportCount = 1
929pp_data->cap[19]->BytePosition = 0x0001
930pp_data->cap[19]->BitCount = 1
931pp_data->cap[19]->BitField = 0x22
932pp_data->cap[19]->NextBytePosition = 0x0002
933pp_data->cap[19]->LinkCollection = 0x0000
934pp_data->cap[19]->LinkUsagePage = 0xFFA0
935pp_data->cap[19]->LinkUsage = 0x0003
936pp_data->cap[19]->IsMultipleItemsForArray = 0
937pp_data->cap[19]->IsButtonCap = 1
938pp_data->cap[19]->IsPadding = 0
939pp_data->cap[19]->IsAbsolute = 1
940pp_data->cap[19]->IsRange = 0
941pp_data->cap[19]->IsAlias = 0
942pp_data->cap[19]->IsStringRange = 0
943pp_data->cap[19]->IsDesignatorRange = 0
944pp_data->cap[19]->Reserved1 = 0x000000
945pp_data->cap[19]->pp_cap->UnknownTokens[0].Token = 0x00
946pp_data->cap[19]->pp_cap->UnknownTokens[0].Reserved = 0x000000
947pp_data->cap[19]->pp_cap->UnknownTokens[0].BitField = 0x00000000
948pp_data->cap[19]->pp_cap->UnknownTokens[1].Token = 0x00
949pp_data->cap[19]->pp_cap->UnknownTokens[1].Reserved = 0x000000
950pp_data->cap[19]->pp_cap->UnknownTokens[1].BitField = 0x00000000
951pp_data->cap[19]->pp_cap->UnknownTokens[2].Token = 0x00
952pp_data->cap[19]->pp_cap->UnknownTokens[2].Reserved = 0x000000
953pp_data->cap[19]->pp_cap->UnknownTokens[2].BitField = 0x00000000
954pp_data->cap[19]->pp_cap->UnknownTokens[3].Token = 0x00
955pp_data->cap[19]->pp_cap->UnknownTokens[3].Reserved = 0x000000
956pp_data->cap[19]->pp_cap->UnknownTokens[3].BitField = 0x00000000
957pp_data->cap[19]->NotRange.Usage = 0x00D8
958pp_data->cap[19]->NotRange.Reserved1 = 0x00D8
959pp_data->cap[19]->NotRange.StringIndex = 0
960pp_data->cap[19]->NotRange.Reserved2 = 0
961pp_data->cap[19]->NotRange.DesignatorIndex = 0
962pp_data->cap[19]->NotRange.Reserved3 = 0
963pp_data->cap[19]->NotRange.DataIndex = 3
964pp_data->cap[19]->NotRange.Reserved4 = 3
965pp_data->cap[19]->Button.LogicalMin = 0
966pp_data->cap[19]->Button.LogicalMax = 0
967pp_data->cap[19]->Units = 0
968pp_data->cap[19]->UnitsExp = 0
969
970pp_data->cap[20]->UsagePage = 0xFFA0
971pp_data->cap[20]->ReportID = 0x1B
972pp_data->cap[20]->BitPosition = 5
973pp_data->cap[20]->BitSize = 1
974pp_data->cap[20]->ReportCount = 1
975pp_data->cap[20]->BytePosition = 0x0002
976pp_data->cap[20]->BitCount = 1
977pp_data->cap[20]->BitField = 0x22
978pp_data->cap[20]->NextBytePosition = 0x0003
979pp_data->cap[20]->LinkCollection = 0x0000
980pp_data->cap[20]->LinkUsagePage = 0xFFA0
981pp_data->cap[20]->LinkUsage = 0x0003
982pp_data->cap[20]->IsMultipleItemsForArray = 0
983pp_data->cap[20]->IsButtonCap = 1
984pp_data->cap[20]->IsPadding = 0
985pp_data->cap[20]->IsAbsolute = 1
986pp_data->cap[20]->IsRange = 0
987pp_data->cap[20]->IsAlias = 0
988pp_data->cap[20]->IsStringRange = 0
989pp_data->cap[20]->IsDesignatorRange = 0
990pp_data->cap[20]->Reserved1 = 0x000000
991pp_data->cap[20]->pp_cap->UnknownTokens[0].Token = 0x00
992pp_data->cap[20]->pp_cap->UnknownTokens[0].Reserved = 0x000000
993pp_data->cap[20]->pp_cap->UnknownTokens[0].BitField = 0x00000000
994pp_data->cap[20]->pp_cap->UnknownTokens[1].Token = 0x00
995pp_data->cap[20]->pp_cap->UnknownTokens[1].Reserved = 0x000000
996pp_data->cap[20]->pp_cap->UnknownTokens[1].BitField = 0x00000000
997pp_data->cap[20]->pp_cap->UnknownTokens[2].Token = 0x00
998pp_data->cap[20]->pp_cap->UnknownTokens[2].Reserved = 0x000000
999pp_data->cap[20]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1000pp_data->cap[20]->pp_cap->UnknownTokens[3].Token = 0x00
1001pp_data->cap[20]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1002pp_data->cap[20]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1003pp_data->cap[20]->NotRange.Usage = 0x002A
1004pp_data->cap[20]->NotRange.Reserved1 = 0x002A
1005pp_data->cap[20]->NotRange.StringIndex = 0
1006pp_data->cap[20]->NotRange.Reserved2 = 0
1007pp_data->cap[20]->NotRange.DesignatorIndex = 0
1008pp_data->cap[20]->NotRange.Reserved3 = 0
1009pp_data->cap[20]->NotRange.DataIndex = 4
1010pp_data->cap[20]->NotRange.Reserved4 = 4
1011pp_data->cap[20]->Button.LogicalMin = 0
1012pp_data->cap[20]->Button.LogicalMax = 0
1013pp_data->cap[20]->Units = 0
1014pp_data->cap[20]->UnitsExp = 0
1015
1016pp_data->cap[21]->UsagePage = 0xFFA0
1017pp_data->cap[21]->ReportID = 0x1B
1018pp_data->cap[21]->BitPosition = 4
1019pp_data->cap[21]->BitSize = 1
1020pp_data->cap[21]->ReportCount = 1
1021pp_data->cap[21]->BytePosition = 0x0002
1022pp_data->cap[21]->BitCount = 1
1023pp_data->cap[21]->BitField = 0x22
1024pp_data->cap[21]->NextBytePosition = 0x0003
1025pp_data->cap[21]->LinkCollection = 0x0000
1026pp_data->cap[21]->LinkUsagePage = 0xFFA0
1027pp_data->cap[21]->LinkUsage = 0x0003
1028pp_data->cap[21]->IsMultipleItemsForArray = 0
1029pp_data->cap[21]->IsButtonCap = 1
1030pp_data->cap[21]->IsPadding = 0
1031pp_data->cap[21]->IsAbsolute = 1
1032pp_data->cap[21]->IsRange = 0
1033pp_data->cap[21]->IsAlias = 0
1034pp_data->cap[21]->IsStringRange = 0
1035pp_data->cap[21]->IsDesignatorRange = 0
1036pp_data->cap[21]->Reserved1 = 0x000000
1037pp_data->cap[21]->pp_cap->UnknownTokens[0].Token = 0x00
1038pp_data->cap[21]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1039pp_data->cap[21]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1040pp_data->cap[21]->pp_cap->UnknownTokens[1].Token = 0x00
1041pp_data->cap[21]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1042pp_data->cap[21]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1043pp_data->cap[21]->pp_cap->UnknownTokens[2].Token = 0x00
1044pp_data->cap[21]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1045pp_data->cap[21]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1046pp_data->cap[21]->pp_cap->UnknownTokens[3].Token = 0x00
1047pp_data->cap[21]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1048pp_data->cap[21]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1049pp_data->cap[21]->NotRange.Usage = 0x0020
1050pp_data->cap[21]->NotRange.Reserved1 = 0x0020
1051pp_data->cap[21]->NotRange.StringIndex = 0
1052pp_data->cap[21]->NotRange.Reserved2 = 0
1053pp_data->cap[21]->NotRange.DesignatorIndex = 0
1054pp_data->cap[21]->NotRange.Reserved3 = 0
1055pp_data->cap[21]->NotRange.DataIndex = 5
1056pp_data->cap[21]->NotRange.Reserved4 = 5
1057pp_data->cap[21]->Button.LogicalMin = 0
1058pp_data->cap[21]->Button.LogicalMax = 0
1059pp_data->cap[21]->Units = 0
1060pp_data->cap[21]->UnitsExp = 0
1061
1062pp_data->cap[22]->UsagePage = 0xFFA0
1063pp_data->cap[22]->ReportID = 0x1B
1064pp_data->cap[22]->BitPosition = 3
1065pp_data->cap[22]->BitSize = 1
1066pp_data->cap[22]->ReportCount = 1
1067pp_data->cap[22]->BytePosition = 0x0002
1068pp_data->cap[22]->BitCount = 1
1069pp_data->cap[22]->BitField = 0x22
1070pp_data->cap[22]->NextBytePosition = 0x0003
1071pp_data->cap[22]->LinkCollection = 0x0000
1072pp_data->cap[22]->LinkUsagePage = 0xFFA0
1073pp_data->cap[22]->LinkUsage = 0x0003
1074pp_data->cap[22]->IsMultipleItemsForArray = 0
1075pp_data->cap[22]->IsButtonCap = 1
1076pp_data->cap[22]->IsPadding = 0
1077pp_data->cap[22]->IsAbsolute = 1
1078pp_data->cap[22]->IsRange = 0
1079pp_data->cap[22]->IsAlias = 0
1080pp_data->cap[22]->IsStringRange = 0
1081pp_data->cap[22]->IsDesignatorRange = 0
1082pp_data->cap[22]->Reserved1 = 0x000000
1083pp_data->cap[22]->pp_cap->UnknownTokens[0].Token = 0x00
1084pp_data->cap[22]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1085pp_data->cap[22]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1086pp_data->cap[22]->pp_cap->UnknownTokens[1].Token = 0x00
1087pp_data->cap[22]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1088pp_data->cap[22]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1089pp_data->cap[22]->pp_cap->UnknownTokens[2].Token = 0x00
1090pp_data->cap[22]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1091pp_data->cap[22]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1092pp_data->cap[22]->pp_cap->UnknownTokens[3].Token = 0x00
1093pp_data->cap[22]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1094pp_data->cap[22]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1095pp_data->cap[22]->NotRange.Usage = 0x001E
1096pp_data->cap[22]->NotRange.Reserved1 = 0x001E
1097pp_data->cap[22]->NotRange.StringIndex = 0
1098pp_data->cap[22]->NotRange.Reserved2 = 0
1099pp_data->cap[22]->NotRange.DesignatorIndex = 0
1100pp_data->cap[22]->NotRange.Reserved3 = 0
1101pp_data->cap[22]->NotRange.DataIndex = 6
1102pp_data->cap[22]->NotRange.Reserved4 = 6
1103pp_data->cap[22]->Button.LogicalMin = 0
1104pp_data->cap[22]->Button.LogicalMax = 0
1105pp_data->cap[22]->Units = 0
1106pp_data->cap[22]->UnitsExp = 0
1107
1108pp_data->cap[23]->UsagePage = 0xFFA0
1109pp_data->cap[23]->ReportID = 0x1B
1110pp_data->cap[23]->BitPosition = 2
1111pp_data->cap[23]->BitSize = 1
1112pp_data->cap[23]->ReportCount = 1
1113pp_data->cap[23]->BytePosition = 0x0002
1114pp_data->cap[23]->BitCount = 1
1115pp_data->cap[23]->BitField = 0x22
1116pp_data->cap[23]->NextBytePosition = 0x0003
1117pp_data->cap[23]->LinkCollection = 0x0000
1118pp_data->cap[23]->LinkUsagePage = 0xFFA0
1119pp_data->cap[23]->LinkUsage = 0x0003
1120pp_data->cap[23]->IsMultipleItemsForArray = 0
1121pp_data->cap[23]->IsButtonCap = 1
1122pp_data->cap[23]->IsPadding = 0
1123pp_data->cap[23]->IsAbsolute = 1
1124pp_data->cap[23]->IsRange = 0
1125pp_data->cap[23]->IsAlias = 0
1126pp_data->cap[23]->IsStringRange = 0
1127pp_data->cap[23]->IsDesignatorRange = 0
1128pp_data->cap[23]->Reserved1 = 0x000000
1129pp_data->cap[23]->pp_cap->UnknownTokens[0].Token = 0x00
1130pp_data->cap[23]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1131pp_data->cap[23]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1132pp_data->cap[23]->pp_cap->UnknownTokens[1].Token = 0x00
1133pp_data->cap[23]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1134pp_data->cap[23]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1135pp_data->cap[23]->pp_cap->UnknownTokens[2].Token = 0x00
1136pp_data->cap[23]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1137pp_data->cap[23]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1138pp_data->cap[23]->pp_cap->UnknownTokens[3].Token = 0x00
1139pp_data->cap[23]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1140pp_data->cap[23]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1141pp_data->cap[23]->NotRange.Usage = 0x0018
1142pp_data->cap[23]->NotRange.Reserved1 = 0x0018
1143pp_data->cap[23]->NotRange.StringIndex = 0
1144pp_data->cap[23]->NotRange.Reserved2 = 0
1145pp_data->cap[23]->NotRange.DesignatorIndex = 0
1146pp_data->cap[23]->NotRange.Reserved3 = 0
1147pp_data->cap[23]->NotRange.DataIndex = 7
1148pp_data->cap[23]->NotRange.Reserved4 = 7
1149pp_data->cap[23]->Button.LogicalMin = 0
1150pp_data->cap[23]->Button.LogicalMax = 0
1151pp_data->cap[23]->Units = 0
1152pp_data->cap[23]->UnitsExp = 0
1153
1154pp_data->cap[24]->UsagePage = 0xFFA0
1155pp_data->cap[24]->ReportID = 0x1B
1156pp_data->cap[24]->BitPosition = 1
1157pp_data->cap[24]->BitSize = 1
1158pp_data->cap[24]->ReportCount = 1
1159pp_data->cap[24]->BytePosition = 0x0002
1160pp_data->cap[24]->BitCount = 1
1161pp_data->cap[24]->BitField = 0x22
1162pp_data->cap[24]->NextBytePosition = 0x0003
1163pp_data->cap[24]->LinkCollection = 0x0000
1164pp_data->cap[24]->LinkUsagePage = 0xFFA0
1165pp_data->cap[24]->LinkUsage = 0x0003
1166pp_data->cap[24]->IsMultipleItemsForArray = 0
1167pp_data->cap[24]->IsButtonCap = 1
1168pp_data->cap[24]->IsPadding = 0
1169pp_data->cap[24]->IsAbsolute = 1
1170pp_data->cap[24]->IsRange = 0
1171pp_data->cap[24]->IsAlias = 0
1172pp_data->cap[24]->IsStringRange = 0
1173pp_data->cap[24]->IsDesignatorRange = 0
1174pp_data->cap[24]->Reserved1 = 0x000000
1175pp_data->cap[24]->pp_cap->UnknownTokens[0].Token = 0x00
1176pp_data->cap[24]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1177pp_data->cap[24]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1178pp_data->cap[24]->pp_cap->UnknownTokens[1].Token = 0x00
1179pp_data->cap[24]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1180pp_data->cap[24]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1181pp_data->cap[24]->pp_cap->UnknownTokens[2].Token = 0x00
1182pp_data->cap[24]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1183pp_data->cap[24]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1184pp_data->cap[24]->pp_cap->UnknownTokens[3].Token = 0x00
1185pp_data->cap[24]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1186pp_data->cap[24]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1187pp_data->cap[24]->NotRange.Usage = 0x0017
1188pp_data->cap[24]->NotRange.Reserved1 = 0x0017
1189pp_data->cap[24]->NotRange.StringIndex = 0
1190pp_data->cap[24]->NotRange.Reserved2 = 0
1191pp_data->cap[24]->NotRange.DesignatorIndex = 0
1192pp_data->cap[24]->NotRange.Reserved3 = 0
1193pp_data->cap[24]->NotRange.DataIndex = 8
1194pp_data->cap[24]->NotRange.Reserved4 = 8
1195pp_data->cap[24]->Button.LogicalMin = 0
1196pp_data->cap[24]->Button.LogicalMax = 0
1197pp_data->cap[24]->Units = 0
1198pp_data->cap[24]->UnitsExp = 0
1199
1200pp_data->cap[25]->UsagePage = 0xFFA0
1201pp_data->cap[25]->ReportID = 0x1B
1202pp_data->cap[25]->BitPosition = 0
1203pp_data->cap[25]->BitSize = 1
1204pp_data->cap[25]->ReportCount = 1
1205pp_data->cap[25]->BytePosition = 0x0002
1206pp_data->cap[25]->BitCount = 1
1207pp_data->cap[25]->BitField = 0x22
1208pp_data->cap[25]->NextBytePosition = 0x0003
1209pp_data->cap[25]->LinkCollection = 0x0000
1210pp_data->cap[25]->LinkUsagePage = 0xFFA0
1211pp_data->cap[25]->LinkUsage = 0x0003
1212pp_data->cap[25]->IsMultipleItemsForArray = 0
1213pp_data->cap[25]->IsButtonCap = 1
1214pp_data->cap[25]->IsPadding = 0
1215pp_data->cap[25]->IsAbsolute = 1
1216pp_data->cap[25]->IsRange = 0
1217pp_data->cap[25]->IsAlias = 0
1218pp_data->cap[25]->IsStringRange = 0
1219pp_data->cap[25]->IsDesignatorRange = 0
1220pp_data->cap[25]->Reserved1 = 0x000000
1221pp_data->cap[25]->pp_cap->UnknownTokens[0].Token = 0x00
1222pp_data->cap[25]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1223pp_data->cap[25]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1224pp_data->cap[25]->pp_cap->UnknownTokens[1].Token = 0x00
1225pp_data->cap[25]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1226pp_data->cap[25]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1227pp_data->cap[25]->pp_cap->UnknownTokens[2].Token = 0x00
1228pp_data->cap[25]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1229pp_data->cap[25]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1230pp_data->cap[25]->pp_cap->UnknownTokens[3].Token = 0x00
1231pp_data->cap[25]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1232pp_data->cap[25]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1233pp_data->cap[25]->NotRange.Usage = 0x0009
1234pp_data->cap[25]->NotRange.Reserved1 = 0x0009
1235pp_data->cap[25]->NotRange.StringIndex = 0
1236pp_data->cap[25]->NotRange.Reserved2 = 0
1237pp_data->cap[25]->NotRange.DesignatorIndex = 0
1238pp_data->cap[25]->NotRange.Reserved3 = 0
1239pp_data->cap[25]->NotRange.DataIndex = 9
1240pp_data->cap[25]->NotRange.Reserved4 = 9
1241pp_data->cap[25]->Button.LogicalMin = 0
1242pp_data->cap[25]->Button.LogicalMax = 0
1243pp_data->cap[25]->Units = 0
1244pp_data->cap[25]->UnitsExp = 0
1245
1246# Link Collections:
1247pp_data->LinkCollectionArray[0]->LinkUsage = 0x0003
1248pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFFA0
1249pp_data->LinkCollectionArray[0]->Parent = 0
1250pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
1251pp_data->LinkCollectionArray[0]->NextSibling = 0
1252pp_data->LinkCollectionArray[0]->FirstChild = 0
1253pp_data->LinkCollectionArray[0]->CollectionType = 1
1254pp_data->LinkCollectionArray[0]->IsAlias = 0
1255pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_expected.rpt_desc
new file mode 100644
index 0000000..ef059c4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_expected.rpt_desc
@@ -0,0 +1,24 @@
10x06, 0xA0, 0xFF, 0x09, 0x03, 0xA1, 0x01, 0x85, 0x03, 0x09,
20x30, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x81,
30x02, 0x85, 0x14, 0x09, 0xB1, 0x09, 0xB2, 0x09, 0xB5, 0x09,
40xB7, 0x09, 0xB3, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95,
50x05, 0x81, 0x06, 0x75, 0x03, 0x95, 0x01, 0x81, 0x03, 0x85,
60x15, 0x09, 0x8C, 0x15, 0x00, 0x27, 0xFF, 0xFF, 0x00, 0x00,
70x75, 0x10, 0x95, 0x01, 0x81, 0x22, 0x85, 0x1F, 0x09, 0x9C,
80x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x06,
90x75, 0x07, 0x95, 0x01, 0x81, 0x03, 0x85, 0x03, 0x09, 0x30,
100x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x91, 0x02,
110x85, 0x19, 0x09, 0x8D, 0x09, 0x8F, 0x09, 0x9E, 0x09, 0xDC,
120x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x04, 0x91, 0x22,
130x09, 0xD2, 0x09, 0xD9, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
140x95, 0x02, 0x91, 0x06, 0x75, 0x02, 0x95, 0x01, 0x91, 0x03,
150x85, 0x1A, 0x09, 0xB5, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
160x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01, 0x91, 0x03,
170x85, 0x1B, 0x09, 0xCF, 0x09, 0xB5, 0x15, 0x00, 0x25, 0x01,
180x75, 0x01, 0x95, 0x02, 0xB1, 0x22, 0x09, 0xDE, 0x15, 0x00,
190x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0xB1, 0x23, 0x09, 0xD8,
200x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0xB1, 0x22,
210x75, 0x04, 0x95, 0x01, 0xB1, 0x03, 0x09, 0x09, 0x09, 0x17,
220x09, 0x18, 0x09, 0x1E, 0x09, 0x20, 0x09, 0x2A, 0x15, 0x00,
230x25, 0x01, 0x75, 0x01, 0x95, 0x06, 0xB1, 0x22, 0x75, 0x02,
240x95, 0x01, 0xB1, 0x03, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_real.rpt_desc
new file mode 100644
index 0000000..7532fd1
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0003_FFA0_real.rpt_desc
@@ -0,0 +1,113 @@
1macOS USB Prober about 0x047F/0xC056 "Plantronics Blackwire 3220 Series"
206 A0 FF 09 03 A1 01 85 03 09 30 75
308 95 20 91 02 85 03 09 30 75 08 95 20 81 02 85
414 09 B1 09 B2 09 B5 09 B7 09 B3 15 00 25 01 75
501 95 05 81 06 95 03 81 01 85 15 09 8C 15 00 27
6FF FF 00 00 75 10 95 01 81 22 85 19 09 8D 09 8F
709 9E 09 DC 15 00 25 01 75 01 95 04 91 22 09 D2
809 D9 15 00 25 01 75 01 95 02 91 06 95 02 91 01
985 1A 09 B5 15 00 25 01 75 01 95 01 91 22 95 07
1091 01 85 1B 09 CF 09 B5 75 01 95 02 B1 22 09 DE
1175 01 95 01 B1 23 09 D8 95 01 B1 22 95 04 B1 01
1209 09 09 17 09 18 09 1E 09 20 09 2A 75 01 95 06
13B1 22 95 02 B1 01 85 1F 09 9C 75 01 95 01 81 06
1495 07 81 01 C0
15
16Parser output:
170x06, 0xA0, 0xFF, // Usage Page (Vendor Defined 0xFFA0)
180x09, 0x03, // Usage (0x03)
190xA1, 0x01, // Collection (Application)
200x85, 0x03, // Report ID (3)
210x09, 0x30, // Usage (0x30)
220x75, 0x08, // Report Size (8)
230x95, 0x20, // Report Count (32)
240x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
250x85, 0x03, // Report ID (3)
260x09, 0x30, // Usage (0x30)
270x75, 0x08, // Report Size (8)
280x95, 0x20, // Report Count (32)
290x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
300x85, 0x14, // Report ID (20)
310x09, 0xB1, // Usage (0xB1)
320x09, 0xB2, // Usage (0xB2)
330x09, 0xB5, // Usage (0xB5)
340x09, 0xB7, // Usage (0xB7)
350x09, 0xB3, // Usage (0xB3)
360x15, 0x00, // Logical Minimum (0)
370x25, 0x01, // Logical Maximum (1)
380x75, 0x01, // Report Size (1)
390x95, 0x05, // Report Count (5)
400x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
410x95, 0x03, // Report Count (3)
420x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
430x85, 0x15, // Report ID (21)
440x09, 0x8C, // Usage (0x8C)
450x15, 0x00, // Logical Minimum (0)
460x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65534)
470x75, 0x10, // Report Size (16)
480x95, 0x01, // Report Count (1)
490x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position)
500x85, 0x19, // Report ID (25)
510x09, 0x8D, // Usage (0x8D)
520x09, 0x8F, // Usage (0x8F)
530x09, 0x9E, // Usage (0x9E)
540x09, 0xDC, // Usage (0xDC)
550x15, 0x00, // Logical Minimum (0)
560x25, 0x01, // Logical Maximum (1)
570x75, 0x01, // Report Size (1)
580x95, 0x04, // Report Count (4)
590x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
600x09, 0xD2, // Usage (0xD2)
610x09, 0xD9, // Usage (0xD9)
620x15, 0x00, // Logical Minimum (0)
630x25, 0x01, // Logical Maximum (1)
640x75, 0x01, // Report Size (1)
650x95, 0x02, // Report Count (2)
660x91, 0x06, // Output (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
670x95, 0x02, // Report Count (2)
680x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
690x85, 0x1A, // Report ID (26)
700x09, 0xB5, // Usage (0xB5)
710x15, 0x00, // Logical Minimum (0)
720x25, 0x01, // Logical Maximum (1)
730x75, 0x01, // Report Size (1)
740x95, 0x01, // Report Count (1)
750x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
760x95, 0x07, // Report Count (7)
770x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
780x85, 0x1B, // Report ID (27)
790x09, 0xCF, // Usage (0xCF)
800x09, 0xB5, // Usage (0xB5)
810x75, 0x01, // Report Size (1)
820x95, 0x02, // Report Count (2)
830xB1, 0x22, // Feature (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
840x09, 0xDE, // Usage (0xDE)
850x75, 0x01, // Report Size (1)
860x95, 0x01, // Report Count (1)
870xB1, 0x23, // Feature (Const,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
880x09, 0xD8, // Usage (0xD8)
890x95, 0x01, // Report Count (1)
900xB1, 0x22, // Feature (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
910x95, 0x04, // Report Count (4)
920xB1, 0x01, // Feature (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
930x09, 0x09, // Usage (0x09)
940x09, 0x17, // Usage (0x17)
950x09, 0x18, // Usage (0x18)
960x09, 0x1E, // Usage (0x1E)
970x09, 0x20, // Usage (0x20)
980x09, 0x2A, // Usage (0x2A)
990x75, 0x01, // Report Size (1)
1000x95, 0x06, // Report Count (6)
1010xB1, 0x22, // Feature (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
1020x95, 0x02, // Report Count (2)
1030xB1, 0x01, // Feature (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
1040x85, 0x1F, // Report ID (31)
1050x09, 0x9C, // Usage (0x9C)
1060x75, 0x01, // Report Size (1)
1070x95, 0x01, // Report Count (1)
1080x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
1090x95, 0x07, // Report Count (7)
1100x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
1110xC0, // End Collection
112
113// 193 bytes
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B.pp_data
new file mode 100644
index 0000000..583c317
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B.pp_data
@@ -0,0 +1,461 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x047F
3dev->product_id = 0xC056
4dev->manufacturer_string = "Plantronics"
5dev->product_string = "Plantronics Blackwire 3220 Series"
6dev->release_number = 0x0210
7dev->interface_number = 3
8dev->usage = 0x0005
9dev->usage_page = 0x000B
10dev->path = "\\?\hid#vid_047f&pid_c056&mi_03&col02#f&39e6f119&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0005
15pp_data->UsagePage = 0x000B
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 3
20pp_data->caps_info[0]->NumberOfCaps = 3
21pp_data->caps_info[0]->ReportByteLength = 2
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 3
24pp_data->caps_info[1]->LastCap = 9
25pp_data->caps_info[1]->NumberOfCaps = 6
26pp_data->caps_info[1]->ReportByteLength = 2
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 9
29pp_data->caps_info[2]->LastCap = 9
30pp_data->caps_info[2]->NumberOfCaps = 0
31pp_data->caps_info[2]->ReportByteLength = 0
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x03A8
34pp_data->NumberLinkCollectionNodes = 1
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0x000B
37pp_data->cap[0]->ReportID = 0x08
38pp_data->cap[0]->BitPosition = 0
39pp_data->cap[0]->BitSize = 1
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0001
42pp_data->cap[0]->BitCount = 1
43pp_data->cap[0]->BitField = 0x06
44pp_data->cap[0]->NextBytePosition = 0x0002
45pp_data->cap[0]->LinkCollection = 0x0000
46pp_data->cap[0]->LinkUsagePage = 0x000B
47pp_data->cap[0]->LinkUsage = 0x0005
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 1
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 0
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x002F
70pp_data->cap[0]->NotRange.Reserved1 = 0x002F
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->Button.LogicalMin = 0
78pp_data->cap[0]->Button.LogicalMax = 0
79pp_data->cap[0]->Units = 0
80pp_data->cap[0]->UnitsExp = 0
81
82pp_data->cap[1]->UsagePage = 0x000B
83pp_data->cap[1]->ReportID = 0x08
84pp_data->cap[1]->BitPosition = 2
85pp_data->cap[1]->BitSize = 1
86pp_data->cap[1]->ReportCount = 1
87pp_data->cap[1]->BytePosition = 0x0001
88pp_data->cap[1]->BitCount = 1
89pp_data->cap[1]->BitField = 0x22
90pp_data->cap[1]->NextBytePosition = 0x0002
91pp_data->cap[1]->LinkCollection = 0x0000
92pp_data->cap[1]->LinkUsagePage = 0x000B
93pp_data->cap[1]->LinkUsage = 0x0005
94pp_data->cap[1]->IsMultipleItemsForArray = 0
95pp_data->cap[1]->IsButtonCap = 1
96pp_data->cap[1]->IsPadding = 0
97pp_data->cap[1]->IsAbsolute = 1
98pp_data->cap[1]->IsRange = 0
99pp_data->cap[1]->IsAlias = 0
100pp_data->cap[1]->IsStringRange = 0
101pp_data->cap[1]->IsDesignatorRange = 0
102pp_data->cap[1]->Reserved1 = 0x000
103pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
104pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
105pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
106pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
107pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
108pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
109pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
110pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
111pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
112pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
113pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
114pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
115pp_data->cap[1]->NotRange.Usage = 0x0021
116pp_data->cap[1]->NotRange.Reserved1 = 0x0021
117pp_data->cap[1]->NotRange.StringIndex = 0
118pp_data->cap[1]->NotRange.Reserved2 = 0
119pp_data->cap[1]->NotRange.DesignatorIndex = 0
120pp_data->cap[1]->NotRange.Reserved3 = 0
121pp_data->cap[1]->NotRange.DataIndex = 1
122pp_data->cap[1]->NotRange.Reserved4 = 1
123pp_data->cap[1]->Button.LogicalMin = 0
124pp_data->cap[1]->Button.LogicalMax = 0
125pp_data->cap[1]->Units = 0
126pp_data->cap[1]->UnitsExp = 0
127
128pp_data->cap[2]->UsagePage = 0x000B
129pp_data->cap[2]->ReportID = 0x08
130pp_data->cap[2]->BitPosition = 1
131pp_data->cap[2]->BitSize = 1
132pp_data->cap[2]->ReportCount = 1
133pp_data->cap[2]->BytePosition = 0x0001
134pp_data->cap[2]->BitCount = 1
135pp_data->cap[2]->BitField = 0x22
136pp_data->cap[2]->NextBytePosition = 0x0002
137pp_data->cap[2]->LinkCollection = 0x0000
138pp_data->cap[2]->LinkUsagePage = 0x000B
139pp_data->cap[2]->LinkUsage = 0x0005
140pp_data->cap[2]->IsMultipleItemsForArray = 0
141pp_data->cap[2]->IsButtonCap = 1
142pp_data->cap[2]->IsPadding = 0
143pp_data->cap[2]->IsAbsolute = 1
144pp_data->cap[2]->IsRange = 0
145pp_data->cap[2]->IsAlias = 0
146pp_data->cap[2]->IsStringRange = 0
147pp_data->cap[2]->IsDesignatorRange = 0
148pp_data->cap[2]->Reserved1 = 0x000
149pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
150pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
151pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
152pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
153pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
154pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
155pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
156pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
157pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
158pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
159pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
160pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
161pp_data->cap[2]->NotRange.Usage = 0x0020
162pp_data->cap[2]->NotRange.Reserved1 = 0x0020
163pp_data->cap[2]->NotRange.StringIndex = 0
164pp_data->cap[2]->NotRange.Reserved2 = 0
165pp_data->cap[2]->NotRange.DesignatorIndex = 0
166pp_data->cap[2]->NotRange.Reserved3 = 0
167pp_data->cap[2]->NotRange.DataIndex = 2
168pp_data->cap[2]->NotRange.Reserved4 = 2
169pp_data->cap[2]->Button.LogicalMin = 0
170pp_data->cap[2]->Button.LogicalMax = 0
171pp_data->cap[2]->Units = 0
172pp_data->cap[2]->UnitsExp = 0
173
174# Output hid_pp_cap struct:
175pp_data->cap[3]->UsagePage = 0x0008
176pp_data->cap[3]->ReportID = 0x09
177pp_data->cap[3]->BitPosition = 0
178pp_data->cap[3]->BitSize = 1
179pp_data->cap[3]->ReportCount = 1
180pp_data->cap[3]->BytePosition = 0x0001
181pp_data->cap[3]->BitCount = 1
182pp_data->cap[3]->BitField = 0x22
183pp_data->cap[3]->NextBytePosition = 0x0002
184pp_data->cap[3]->LinkCollection = 0x0000
185pp_data->cap[3]->LinkUsagePage = 0x000B
186pp_data->cap[3]->LinkUsage = 0x0005
187pp_data->cap[3]->IsMultipleItemsForArray = 0
188pp_data->cap[3]->IsButtonCap = 1
189pp_data->cap[3]->IsPadding = 0
190pp_data->cap[3]->IsAbsolute = 1
191pp_data->cap[3]->IsRange = 0
192pp_data->cap[3]->IsAlias = 0
193pp_data->cap[3]->IsStringRange = 0
194pp_data->cap[3]->IsDesignatorRange = 0
195pp_data->cap[3]->Reserved1 = 0x000
196pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
197pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
198pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
199pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
200pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
201pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
202pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
203pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
204pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
205pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
206pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
207pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
208pp_data->cap[3]->NotRange.Usage = 0x0009
209pp_data->cap[3]->NotRange.Reserved1 = 0x0009
210pp_data->cap[3]->NotRange.StringIndex = 0
211pp_data->cap[3]->NotRange.Reserved2 = 0
212pp_data->cap[3]->NotRange.DesignatorIndex = 0
213pp_data->cap[3]->NotRange.Reserved3 = 0
214pp_data->cap[3]->NotRange.DataIndex = 0
215pp_data->cap[3]->NotRange.Reserved4 = 0
216pp_data->cap[3]->Button.LogicalMin = 0
217pp_data->cap[3]->Button.LogicalMax = 0
218pp_data->cap[3]->Units = 0
219pp_data->cap[3]->UnitsExp = 0
220
221pp_data->cap[4]->UsagePage = 0x0008
222pp_data->cap[4]->ReportID = 0x17
223pp_data->cap[4]->BitPosition = 0
224pp_data->cap[4]->BitSize = 1
225pp_data->cap[4]->ReportCount = 1
226pp_data->cap[4]->BytePosition = 0x0001
227pp_data->cap[4]->BitCount = 1
228pp_data->cap[4]->BitField = 0x22
229pp_data->cap[4]->NextBytePosition = 0x0002
230pp_data->cap[4]->LinkCollection = 0x0000
231pp_data->cap[4]->LinkUsagePage = 0x000B
232pp_data->cap[4]->LinkUsage = 0x0005
233pp_data->cap[4]->IsMultipleItemsForArray = 0
234pp_data->cap[4]->IsButtonCap = 1
235pp_data->cap[4]->IsPadding = 0
236pp_data->cap[4]->IsAbsolute = 1
237pp_data->cap[4]->IsRange = 0
238pp_data->cap[4]->IsAlias = 0
239pp_data->cap[4]->IsStringRange = 0
240pp_data->cap[4]->IsDesignatorRange = 0
241pp_data->cap[4]->Reserved1 = 0x000
242pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
243pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
244pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
245pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
246pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
247pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
248pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
249pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
250pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
251pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
252pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
253pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
254pp_data->cap[4]->NotRange.Usage = 0x0017
255pp_data->cap[4]->NotRange.Reserved1 = 0x0017
256pp_data->cap[4]->NotRange.StringIndex = 0
257pp_data->cap[4]->NotRange.Reserved2 = 0
258pp_data->cap[4]->NotRange.DesignatorIndex = 0
259pp_data->cap[4]->NotRange.Reserved3 = 0
260pp_data->cap[4]->NotRange.DataIndex = 1
261pp_data->cap[4]->NotRange.Reserved4 = 1
262pp_data->cap[4]->Button.LogicalMin = 0
263pp_data->cap[4]->Button.LogicalMax = 0
264pp_data->cap[4]->Units = 0
265pp_data->cap[4]->UnitsExp = 0
266
267pp_data->cap[5]->UsagePage = 0x0008
268pp_data->cap[5]->ReportID = 0x18
269pp_data->cap[5]->BitPosition = 0
270pp_data->cap[5]->BitSize = 1
271pp_data->cap[5]->ReportCount = 1
272pp_data->cap[5]->BytePosition = 0x0001
273pp_data->cap[5]->BitCount = 1
274pp_data->cap[5]->BitField = 0x22
275pp_data->cap[5]->NextBytePosition = 0x0002
276pp_data->cap[5]->LinkCollection = 0x0000
277pp_data->cap[5]->LinkUsagePage = 0x000B
278pp_data->cap[5]->LinkUsage = 0x0005
279pp_data->cap[5]->IsMultipleItemsForArray = 0
280pp_data->cap[5]->IsButtonCap = 1
281pp_data->cap[5]->IsPadding = 0
282pp_data->cap[5]->IsAbsolute = 1
283pp_data->cap[5]->IsRange = 0
284pp_data->cap[5]->IsAlias = 0
285pp_data->cap[5]->IsStringRange = 0
286pp_data->cap[5]->IsDesignatorRange = 0
287pp_data->cap[5]->Reserved1 = 0x000
288pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
289pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
290pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
291pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
292pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
293pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
294pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
295pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
296pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
297pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
298pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
299pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
300pp_data->cap[5]->NotRange.Usage = 0x0018
301pp_data->cap[5]->NotRange.Reserved1 = 0x0018
302pp_data->cap[5]->NotRange.StringIndex = 0
303pp_data->cap[5]->NotRange.Reserved2 = 0
304pp_data->cap[5]->NotRange.DesignatorIndex = 0
305pp_data->cap[5]->NotRange.Reserved3 = 0
306pp_data->cap[5]->NotRange.DataIndex = 2
307pp_data->cap[5]->NotRange.Reserved4 = 2
308pp_data->cap[5]->Button.LogicalMin = 0
309pp_data->cap[5]->Button.LogicalMax = 0
310pp_data->cap[5]->Units = 0
311pp_data->cap[5]->UnitsExp = 0
312
313pp_data->cap[6]->UsagePage = 0x0008
314pp_data->cap[6]->ReportID = 0x1E
315pp_data->cap[6]->BitPosition = 0
316pp_data->cap[6]->BitSize = 1
317pp_data->cap[6]->ReportCount = 1
318pp_data->cap[6]->BytePosition = 0x0001
319pp_data->cap[6]->BitCount = 1
320pp_data->cap[6]->BitField = 0x22
321pp_data->cap[6]->NextBytePosition = 0x0002
322pp_data->cap[6]->LinkCollection = 0x0000
323pp_data->cap[6]->LinkUsagePage = 0x000B
324pp_data->cap[6]->LinkUsage = 0x0005
325pp_data->cap[6]->IsMultipleItemsForArray = 0
326pp_data->cap[6]->IsButtonCap = 1
327pp_data->cap[6]->IsPadding = 0
328pp_data->cap[6]->IsAbsolute = 1
329pp_data->cap[6]->IsRange = 0
330pp_data->cap[6]->IsAlias = 0
331pp_data->cap[6]->IsStringRange = 0
332pp_data->cap[6]->IsDesignatorRange = 0
333pp_data->cap[6]->Reserved1 = 0x000
334pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
335pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
336pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
337pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
338pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
339pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
340pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
341pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
342pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
343pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
344pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
345pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
346pp_data->cap[6]->NotRange.Usage = 0x001E
347pp_data->cap[6]->NotRange.Reserved1 = 0x001E
348pp_data->cap[6]->NotRange.StringIndex = 0
349pp_data->cap[6]->NotRange.Reserved2 = 0
350pp_data->cap[6]->NotRange.DesignatorIndex = 0
351pp_data->cap[6]->NotRange.Reserved3 = 0
352pp_data->cap[6]->NotRange.DataIndex = 3
353pp_data->cap[6]->NotRange.Reserved4 = 3
354pp_data->cap[6]->Button.LogicalMin = 0
355pp_data->cap[6]->Button.LogicalMax = 0
356pp_data->cap[6]->Units = 0
357pp_data->cap[6]->UnitsExp = 0
358
359pp_data->cap[7]->UsagePage = 0x0008
360pp_data->cap[7]->ReportID = 0x20
361pp_data->cap[7]->BitPosition = 0
362pp_data->cap[7]->BitSize = 1
363pp_data->cap[7]->ReportCount = 1
364pp_data->cap[7]->BytePosition = 0x0001
365pp_data->cap[7]->BitCount = 1
366pp_data->cap[7]->BitField = 0x22
367pp_data->cap[7]->NextBytePosition = 0x0002
368pp_data->cap[7]->LinkCollection = 0x0000
369pp_data->cap[7]->LinkUsagePage = 0x000B
370pp_data->cap[7]->LinkUsage = 0x0005
371pp_data->cap[7]->IsMultipleItemsForArray = 0
372pp_data->cap[7]->IsButtonCap = 1
373pp_data->cap[7]->IsPadding = 0
374pp_data->cap[7]->IsAbsolute = 1
375pp_data->cap[7]->IsRange = 0
376pp_data->cap[7]->IsAlias = 0
377pp_data->cap[7]->IsStringRange = 0
378pp_data->cap[7]->IsDesignatorRange = 0
379pp_data->cap[7]->Reserved1 = 0x000
380pp_data->cap[7]->pp_cap->UnknownTokens[0].Token = 0x00
381pp_data->cap[7]->pp_cap->UnknownTokens[0].Reserved = 0x000000
382pp_data->cap[7]->pp_cap->UnknownTokens[0].BitField = 0x00000000
383pp_data->cap[7]->pp_cap->UnknownTokens[1].Token = 0x00
384pp_data->cap[7]->pp_cap->UnknownTokens[1].Reserved = 0x000000
385pp_data->cap[7]->pp_cap->UnknownTokens[1].BitField = 0x00000000
386pp_data->cap[7]->pp_cap->UnknownTokens[2].Token = 0x00
387pp_data->cap[7]->pp_cap->UnknownTokens[2].Reserved = 0x000000
388pp_data->cap[7]->pp_cap->UnknownTokens[2].BitField = 0x00000000
389pp_data->cap[7]->pp_cap->UnknownTokens[3].Token = 0x00
390pp_data->cap[7]->pp_cap->UnknownTokens[3].Reserved = 0x000000
391pp_data->cap[7]->pp_cap->UnknownTokens[3].BitField = 0x00000000
392pp_data->cap[7]->NotRange.Usage = 0x0020
393pp_data->cap[7]->NotRange.Reserved1 = 0x0020
394pp_data->cap[7]->NotRange.StringIndex = 0
395pp_data->cap[7]->NotRange.Reserved2 = 0
396pp_data->cap[7]->NotRange.DesignatorIndex = 0
397pp_data->cap[7]->NotRange.Reserved3 = 0
398pp_data->cap[7]->NotRange.DataIndex = 4
399pp_data->cap[7]->NotRange.Reserved4 = 4
400pp_data->cap[7]->Button.LogicalMin = 0
401pp_data->cap[7]->Button.LogicalMax = 0
402pp_data->cap[7]->Units = 0
403pp_data->cap[7]->UnitsExp = 0
404
405pp_data->cap[8]->UsagePage = 0x0008
406pp_data->cap[8]->ReportID = 0x2A
407pp_data->cap[8]->BitPosition = 0
408pp_data->cap[8]->BitSize = 1
409pp_data->cap[8]->ReportCount = 1
410pp_data->cap[8]->BytePosition = 0x0001
411pp_data->cap[8]->BitCount = 1
412pp_data->cap[8]->BitField = 0x22
413pp_data->cap[8]->NextBytePosition = 0x0002
414pp_data->cap[8]->LinkCollection = 0x0000
415pp_data->cap[8]->LinkUsagePage = 0x000B
416pp_data->cap[8]->LinkUsage = 0x0005
417pp_data->cap[8]->IsMultipleItemsForArray = 0
418pp_data->cap[8]->IsButtonCap = 1
419pp_data->cap[8]->IsPadding = 0
420pp_data->cap[8]->IsAbsolute = 1
421pp_data->cap[8]->IsRange = 0
422pp_data->cap[8]->IsAlias = 0
423pp_data->cap[8]->IsStringRange = 0
424pp_data->cap[8]->IsDesignatorRange = 0
425pp_data->cap[8]->Reserved1 = 0x000
426pp_data->cap[8]->pp_cap->UnknownTokens[0].Token = 0x00
427pp_data->cap[8]->pp_cap->UnknownTokens[0].Reserved = 0x000000
428pp_data->cap[8]->pp_cap->UnknownTokens[0].BitField = 0x00000000
429pp_data->cap[8]->pp_cap->UnknownTokens[1].Token = 0x00
430pp_data->cap[8]->pp_cap->UnknownTokens[1].Reserved = 0x000000
431pp_data->cap[8]->pp_cap->UnknownTokens[1].BitField = 0x00000000
432pp_data->cap[8]->pp_cap->UnknownTokens[2].Token = 0x00
433pp_data->cap[8]->pp_cap->UnknownTokens[2].Reserved = 0x000000
434pp_data->cap[8]->pp_cap->UnknownTokens[2].BitField = 0x00000000
435pp_data->cap[8]->pp_cap->UnknownTokens[3].Token = 0x00
436pp_data->cap[8]->pp_cap->UnknownTokens[3].Reserved = 0x000000
437pp_data->cap[8]->pp_cap->UnknownTokens[3].BitField = 0x00000000
438pp_data->cap[8]->NotRange.Usage = 0x002A
439pp_data->cap[8]->NotRange.Reserved1 = 0x002A
440pp_data->cap[8]->NotRange.StringIndex = 0
441pp_data->cap[8]->NotRange.Reserved2 = 0
442pp_data->cap[8]->NotRange.DesignatorIndex = 0
443pp_data->cap[8]->NotRange.Reserved3 = 0
444pp_data->cap[8]->NotRange.DataIndex = 5
445pp_data->cap[8]->NotRange.Reserved4 = 5
446pp_data->cap[8]->Button.LogicalMin = 0
447pp_data->cap[8]->Button.LogicalMax = 0
448pp_data->cap[8]->Units = 0
449pp_data->cap[8]->UnitsExp = 0
450
451# Feature hid_pp_cap struct:
452# Link Collections:
453pp_data->LinkCollectionArray[0]->LinkUsage = 0x0005
454pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000B
455pp_data->LinkCollectionArray[0]->Parent = 0
456pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
457pp_data->LinkCollectionArray[0]->NextSibling = 0
458pp_data->LinkCollectionArray[0]->FirstChild = 0
459pp_data->LinkCollectionArray[0]->CollectionType = 1
460pp_data->LinkCollectionArray[0]->IsAlias = 0
461pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_expected.rpt_desc
new file mode 100644
index 0000000..40962ac
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_expected.rpt_desc
@@ -0,0 +1,17 @@
10x05, 0x0B, 0x09, 0x05, 0xA1, 0x01, 0x85, 0x08, 0x09, 0x2F,
20x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x06,
30x09, 0x20, 0x09, 0x21, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
40x95, 0x02, 0x81, 0x22, 0x75, 0x05, 0x95, 0x01, 0x81, 0x03,
50x85, 0x09, 0x05, 0x08, 0x09, 0x09, 0x15, 0x00, 0x25, 0x01,
60x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
70x91, 0x03, 0x85, 0x17, 0x09, 0x17, 0x15, 0x00, 0x25, 0x01,
80x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
90x91, 0x03, 0x85, 0x18, 0x09, 0x18, 0x15, 0x00, 0x25, 0x01,
100x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
110x91, 0x03, 0x85, 0x1E, 0x09, 0x1E, 0x15, 0x00, 0x25, 0x01,
120x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
130x91, 0x03, 0x85, 0x20, 0x09, 0x20, 0x15, 0x00, 0x25, 0x01,
140x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
150x91, 0x03, 0x85, 0x2A, 0x09, 0x2A, 0x15, 0x00, 0x25, 0x01,
160x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
170x91, 0x03, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_real.rpt_desc
new file mode 100644
index 0000000..2fe387e
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/047F_C056_0005_000B_real.rpt_desc
@@ -0,0 +1,68 @@
1macOS USB Prober about 0x047F/0xC056 "Plantronics Blackwire 3220 Series"
205 0B 09 05 A1 01 85 08 15
300 25 01 09 2F 75 01 95 01 81 06 09 20 09 21 75
401 95 02 81 22 95 05 81 01 05 08 85 09 09 09 95
501 91 22 95 07 91 01 85 17 09 17 95 01 91 22 95
607 91 01 85 18 09 18 95 01 91 22 95 07 91 01 85
71E 09 1E 95 01 91 22 95 07 91 01 85 20 09 20 95
801 91 22 95 07 91 01 85 2A 09 2A 95 01 91 22 95
907 91 01 C0
10
11Parser output:
120x05, 0x0B, // Usage Page (Telephony)
130x09, 0x05, // Usage (Headset)
140xA1, 0x01, // Collection (Application)
150x85, 0x08, // Report ID (8)
160x15, 0x00, // Logical Minimum (0)
170x25, 0x01, // Logical Maximum (1)
180x09, 0x2F, // Usage (Phone Mute)
190x75, 0x01, // Report Size (1)
200x95, 0x01, // Report Count (1)
210x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
220x09, 0x20, // Usage (Hook Switch)
230x09, 0x21, // Usage (Flash)
240x75, 0x01, // Report Size (1)
250x95, 0x02, // Report Count (2)
260x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position)
270x95, 0x05, // Report Count (5)
280x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
290x05, 0x08, // Usage Page (LEDs)
300x85, 0x09, // Report ID (9)
310x09, 0x09, // Usage (Mute)
320x95, 0x01, // Report Count (1)
330x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
340x95, 0x07, // Report Count (7)
350x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
360x85, 0x17, // Report ID (23)
370x09, 0x17, // Usage (Off-Hook)
380x95, 0x01, // Report Count (1)
390x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
400x95, 0x07, // Report Count (7)
410x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
420x85, 0x18, // Report ID (24)
430x09, 0x18, // Usage (Ring)
440x95, 0x01, // Report Count (1)
450x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
460x95, 0x07, // Report Count (7)
470x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
480x85, 0x1E, // Report ID (30)
490x09, 0x1E, // Usage (Speaker)
500x95, 0x01, // Report Count (1)
510x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
520x95, 0x07, // Report Count (7)
530x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
540x85, 0x20, // Report ID (32)
550x09, 0x20, // Usage (Hold)
560x95, 0x01, // Report Count (1)
570x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
580x95, 0x07, // Report Count (7)
590x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
600x85, 0x2A, // Report ID (42)
610x09, 0x2A, // Usage (On-Line)
620x95, 0x01, // Report Count (1)
630x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
640x95, 0x07, // Report Count (7)
650x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
660xC0, // End Collection
67
68// 109 bytes
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01.pp_data b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01.pp_data
new file mode 100644
index 0000000..acab8a6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01.pp_data
@@ -0,0 +1,11508 @@
1# HIDAPI device info struct:
2dev->vendor_id = 0x17CC
3dev->product_id = 0x1130
4dev->manufacturer_string = "Native Instruments"
5dev->product_string = "Traktor Kontrol Z2"
6dev->release_number = 0x0033
7dev->interface_number = 4
8dev->usage = 0x0000
9dev->usage_page = 0xFF01
10dev->path = "\\?\hid#vid_17cc&pid_1130&mi_04#9&11d406cd&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
11
12# Preparsed Data struct:
13pp_data->MagicKey = 0x48696450204B4452
14pp_data->Usage = 0x0000
15pp_data->UsagePage = 0xFF01
16pp_data->Reserved = 0x00000000
17# Input caps_info struct:
18pp_data->caps_info[0]->FirstCap = 0
19pp_data->caps_info[0]->LastCap = 86
20pp_data->caps_info[0]->NumberOfCaps = 87
21pp_data->caps_info[0]->ReportByteLength = 53
22# Output caps_info struct:
23pp_data->caps_info[1]->FirstCap = 87
24pp_data->caps_info[1]->LastCap = 221
25pp_data->caps_info[1]->NumberOfCaps = 134
26pp_data->caps_info[1]->ReportByteLength = 95
27# Feature caps_info struct:
28pp_data->caps_info[2]->FirstCap = 221
29pp_data->caps_info[2]->LastCap = 232
30pp_data->caps_info[2]->NumberOfCaps = 11
31pp_data->caps_info[2]->ReportByteLength = 33
32# LinkCollectionArray Offset & Size:
33pp_data->FirstByteOfLinkCollectionArray = 0x5E40
34pp_data->NumberLinkCollectionNodes = 16
35# Input hid_pp_cap struct:
36pp_data->cap[0]->UsagePage = 0xFF01
37pp_data->cap[0]->ReportID = 0x01
38pp_data->cap[0]->BitPosition = 4
39pp_data->cap[0]->BitSize = 4
40pp_data->cap[0]->ReportCount = 1
41pp_data->cap[0]->BytePosition = 0x0002
42pp_data->cap[0]->BitCount = 4
43pp_data->cap[0]->BitField = 0x02
44pp_data->cap[0]->NextBytePosition = 0x0003
45pp_data->cap[0]->LinkCollection = 0x0001
46pp_data->cap[0]->LinkUsagePage = 0xFF01
47pp_data->cap[0]->LinkUsage = 0x0001
48pp_data->cap[0]->IsMultipleItemsForArray = 0
49pp_data->cap[0]->IsButtonCap = 0
50pp_data->cap[0]->IsPadding = 0
51pp_data->cap[0]->IsAbsolute = 1
52pp_data->cap[0]->IsRange = 0
53pp_data->cap[0]->IsAlias = 0
54pp_data->cap[0]->IsStringRange = 0
55pp_data->cap[0]->IsDesignatorRange = 0
56pp_data->cap[0]->Reserved1 = 0x000000
57pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
58pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
59pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
60pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
61pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
62pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
63pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
64pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
65pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
66pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
67pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
68pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
69pp_data->cap[0]->NotRange.Usage = 0x0003
70pp_data->cap[0]->NotRange.Reserved1 = 0x0003
71pp_data->cap[0]->NotRange.StringIndex = 0
72pp_data->cap[0]->NotRange.Reserved2 = 0
73pp_data->cap[0]->NotRange.DesignatorIndex = 0
74pp_data->cap[0]->NotRange.Reserved3 = 0
75pp_data->cap[0]->NotRange.DataIndex = 0
76pp_data->cap[0]->NotRange.Reserved4 = 0
77pp_data->cap[0]->NotButton.HasNull = 0
78pp_data->cap[0]->NotButton.Reserved4 = 0x000000
79pp_data->cap[0]->NotButton.LogicalMin = 0
80pp_data->cap[0]->NotButton.LogicalMax = 15
81pp_data->cap[0]->NotButton.PhysicalMin = 0
82pp_data->cap[0]->NotButton.PhysicalMax = 0
83pp_data->cap[0]->Units = 0
84pp_data->cap[0]->UnitsExp = 0
85
86pp_data->cap[1]->UsagePage = 0xFF01
87pp_data->cap[1]->ReportID = 0x01
88pp_data->cap[1]->BitPosition = 0
89pp_data->cap[1]->BitSize = 4
90pp_data->cap[1]->ReportCount = 1
91pp_data->cap[1]->BytePosition = 0x0002
92pp_data->cap[1]->BitCount = 4
93pp_data->cap[1]->BitField = 0x02
94pp_data->cap[1]->NextBytePosition = 0x0003
95pp_data->cap[1]->LinkCollection = 0x0001
96pp_data->cap[1]->LinkUsagePage = 0xFF01
97pp_data->cap[1]->LinkUsage = 0x0001
98pp_data->cap[1]->IsMultipleItemsForArray = 0
99pp_data->cap[1]->IsButtonCap = 0
100pp_data->cap[1]->IsPadding = 0
101pp_data->cap[1]->IsAbsolute = 1
102pp_data->cap[1]->IsRange = 0
103pp_data->cap[1]->IsAlias = 0
104pp_data->cap[1]->IsStringRange = 0
105pp_data->cap[1]->IsDesignatorRange = 0
106pp_data->cap[1]->Reserved1 = 0x000000
107pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
108pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
109pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
110pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
111pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
112pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
113pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
114pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
115pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
116pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
117pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
118pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
119pp_data->cap[1]->NotRange.Usage = 0x0003
120pp_data->cap[1]->NotRange.Reserved1 = 0x0003
121pp_data->cap[1]->NotRange.StringIndex = 0
122pp_data->cap[1]->NotRange.Reserved2 = 0
123pp_data->cap[1]->NotRange.DesignatorIndex = 0
124pp_data->cap[1]->NotRange.Reserved3 = 0
125pp_data->cap[1]->NotRange.DataIndex = 1
126pp_data->cap[1]->NotRange.Reserved4 = 1
127pp_data->cap[1]->NotButton.HasNull = 0
128pp_data->cap[1]->NotButton.Reserved4 = 0x000000
129pp_data->cap[1]->NotButton.LogicalMin = 0
130pp_data->cap[1]->NotButton.LogicalMax = 15
131pp_data->cap[1]->NotButton.PhysicalMin = 0
132pp_data->cap[1]->NotButton.PhysicalMax = 0
133pp_data->cap[1]->Units = 0
134pp_data->cap[1]->UnitsExp = 0
135
136pp_data->cap[2]->UsagePage = 0xFF01
137pp_data->cap[2]->ReportID = 0x01
138pp_data->cap[2]->BitPosition = 4
139pp_data->cap[2]->BitSize = 4
140pp_data->cap[2]->ReportCount = 1
141pp_data->cap[2]->BytePosition = 0x0001
142pp_data->cap[2]->BitCount = 4
143pp_data->cap[2]->BitField = 0x02
144pp_data->cap[2]->NextBytePosition = 0x0002
145pp_data->cap[2]->LinkCollection = 0x0001
146pp_data->cap[2]->LinkUsagePage = 0xFF01
147pp_data->cap[2]->LinkUsage = 0x0001
148pp_data->cap[2]->IsMultipleItemsForArray = 0
149pp_data->cap[2]->IsButtonCap = 0
150pp_data->cap[2]->IsPadding = 0
151pp_data->cap[2]->IsAbsolute = 1
152pp_data->cap[2]->IsRange = 0
153pp_data->cap[2]->IsAlias = 0
154pp_data->cap[2]->IsStringRange = 0
155pp_data->cap[2]->IsDesignatorRange = 0
156pp_data->cap[2]->Reserved1 = 0x000000
157pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
158pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
159pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
160pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
161pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
162pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
163pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
164pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
165pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
166pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
167pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
168pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
169pp_data->cap[2]->NotRange.Usage = 0x0003
170pp_data->cap[2]->NotRange.Reserved1 = 0x0003
171pp_data->cap[2]->NotRange.StringIndex = 0
172pp_data->cap[2]->NotRange.Reserved2 = 0
173pp_data->cap[2]->NotRange.DesignatorIndex = 0
174pp_data->cap[2]->NotRange.Reserved3 = 0
175pp_data->cap[2]->NotRange.DataIndex = 2
176pp_data->cap[2]->NotRange.Reserved4 = 2
177pp_data->cap[2]->NotButton.HasNull = 0
178pp_data->cap[2]->NotButton.Reserved4 = 0x000000
179pp_data->cap[2]->NotButton.LogicalMin = 0
180pp_data->cap[2]->NotButton.LogicalMax = 15
181pp_data->cap[2]->NotButton.PhysicalMin = 0
182pp_data->cap[2]->NotButton.PhysicalMax = 0
183pp_data->cap[2]->Units = 0
184pp_data->cap[2]->UnitsExp = 0
185
186pp_data->cap[3]->UsagePage = 0xFF01
187pp_data->cap[3]->ReportID = 0x01
188pp_data->cap[3]->BitPosition = 0
189pp_data->cap[3]->BitSize = 4
190pp_data->cap[3]->ReportCount = 1
191pp_data->cap[3]->BytePosition = 0x0001
192pp_data->cap[3]->BitCount = 4
193pp_data->cap[3]->BitField = 0x02
194pp_data->cap[3]->NextBytePosition = 0x0002
195pp_data->cap[3]->LinkCollection = 0x0001
196pp_data->cap[3]->LinkUsagePage = 0xFF01
197pp_data->cap[3]->LinkUsage = 0x0001
198pp_data->cap[3]->IsMultipleItemsForArray = 0
199pp_data->cap[3]->IsButtonCap = 0
200pp_data->cap[3]->IsPadding = 0
201pp_data->cap[3]->IsAbsolute = 1
202pp_data->cap[3]->IsRange = 0
203pp_data->cap[3]->IsAlias = 0
204pp_data->cap[3]->IsStringRange = 0
205pp_data->cap[3]->IsDesignatorRange = 0
206pp_data->cap[3]->Reserved1 = 0x000000
207pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
208pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
209pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
210pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
211pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
212pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
213pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
214pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
215pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
216pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
217pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
218pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
219pp_data->cap[3]->NotRange.Usage = 0x0003
220pp_data->cap[3]->NotRange.Reserved1 = 0x0003
221pp_data->cap[3]->NotRange.StringIndex = 0
222pp_data->cap[3]->NotRange.Reserved2 = 0
223pp_data->cap[3]->NotRange.DesignatorIndex = 0
224pp_data->cap[3]->NotRange.Reserved3 = 0
225pp_data->cap[3]->NotRange.DataIndex = 3
226pp_data->cap[3]->NotRange.Reserved4 = 3
227pp_data->cap[3]->NotButton.HasNull = 0
228pp_data->cap[3]->NotButton.Reserved4 = 0x000000
229pp_data->cap[3]->NotButton.LogicalMin = 0
230pp_data->cap[3]->NotButton.LogicalMax = 15
231pp_data->cap[3]->NotButton.PhysicalMin = 0
232pp_data->cap[3]->NotButton.PhysicalMax = 0
233pp_data->cap[3]->Units = 0
234pp_data->cap[3]->UnitsExp = 0
235
236pp_data->cap[4]->UsagePage = 0xFF01
237pp_data->cap[4]->ReportID = 0x01
238pp_data->cap[4]->BitPosition = 7
239pp_data->cap[4]->BitSize = 1
240pp_data->cap[4]->ReportCount = 1
241pp_data->cap[4]->BytePosition = 0x0008
242pp_data->cap[4]->BitCount = 1
243pp_data->cap[4]->BitField = 0x02
244pp_data->cap[4]->NextBytePosition = 0x0009
245pp_data->cap[4]->LinkCollection = 0x0001
246pp_data->cap[4]->LinkUsagePage = 0xFF01
247pp_data->cap[4]->LinkUsage = 0x0001
248pp_data->cap[4]->IsMultipleItemsForArray = 0
249pp_data->cap[4]->IsButtonCap = 1
250pp_data->cap[4]->IsPadding = 0
251pp_data->cap[4]->IsAbsolute = 1
252pp_data->cap[4]->IsRange = 0
253pp_data->cap[4]->IsAlias = 0
254pp_data->cap[4]->IsStringRange = 0
255pp_data->cap[4]->IsDesignatorRange = 0
256pp_data->cap[4]->Reserved1 = 0x000000
257pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
258pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
259pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
260pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
261pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
262pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
263pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
264pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
265pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
266pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
267pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
268pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
269pp_data->cap[4]->NotRange.Usage = 0x0002
270pp_data->cap[4]->NotRange.Reserved1 = 0x0002
271pp_data->cap[4]->NotRange.StringIndex = 0
272pp_data->cap[4]->NotRange.Reserved2 = 0
273pp_data->cap[4]->NotRange.DesignatorIndex = 0
274pp_data->cap[4]->NotRange.Reserved3 = 0
275pp_data->cap[4]->NotRange.DataIndex = 4
276pp_data->cap[4]->NotRange.Reserved4 = 4
277pp_data->cap[4]->Button.LogicalMin = 0
278pp_data->cap[4]->Button.LogicalMax = 0
279pp_data->cap[4]->Units = 0
280pp_data->cap[4]->UnitsExp = 0
281
282pp_data->cap[5]->UsagePage = 0xFF01
283pp_data->cap[5]->ReportID = 0x01
284pp_data->cap[5]->BitPosition = 6
285pp_data->cap[5]->BitSize = 1
286pp_data->cap[5]->ReportCount = 1
287pp_data->cap[5]->BytePosition = 0x0008
288pp_data->cap[5]->BitCount = 1
289pp_data->cap[5]->BitField = 0x02
290pp_data->cap[5]->NextBytePosition = 0x0009
291pp_data->cap[5]->LinkCollection = 0x0001
292pp_data->cap[5]->LinkUsagePage = 0xFF01
293pp_data->cap[5]->LinkUsage = 0x0001
294pp_data->cap[5]->IsMultipleItemsForArray = 0
295pp_data->cap[5]->IsButtonCap = 1
296pp_data->cap[5]->IsPadding = 0
297pp_data->cap[5]->IsAbsolute = 1
298pp_data->cap[5]->IsRange = 0
299pp_data->cap[5]->IsAlias = 0
300pp_data->cap[5]->IsStringRange = 0
301pp_data->cap[5]->IsDesignatorRange = 0
302pp_data->cap[5]->Reserved1 = 0x000000
303pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
304pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
305pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
306pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
307pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
308pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
309pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
310pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
311pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
312pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
313pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
314pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
315pp_data->cap[5]->NotRange.Usage = 0x0002
316pp_data->cap[5]->NotRange.Reserved1 = 0x0002
317pp_data->cap[5]->NotRange.StringIndex = 0
318pp_data->cap[5]->NotRange.Reserved2 = 0
319pp_data->cap[5]->NotRange.DesignatorIndex = 0
320pp_data->cap[5]->NotRange.Reserved3 = 0
321pp_data->cap[5]->NotRange.DataIndex = 5
322pp_data->cap[5]->NotRange.Reserved4 = 5
323pp_data->cap[5]->Button.LogicalMin = 0
324pp_data->cap[5]->Button.LogicalMax = 0
325pp_data->cap[5]->Units = 0
326pp_data->cap[5]->UnitsExp = 0
327
328pp_data->cap[6]->UsagePage = 0xFF01
329pp_data->cap[6]->ReportID = 0x01
330pp_data->cap[6]->BitPosition = 5
331pp_data->cap[6]->BitSize = 1
332pp_data->cap[6]->ReportCount = 1
333pp_data->cap[6]->BytePosition = 0x0008
334pp_data->cap[6]->BitCount = 1
335pp_data->cap[6]->BitField = 0x02
336pp_data->cap[6]->NextBytePosition = 0x0009
337pp_data->cap[6]->LinkCollection = 0x0001
338pp_data->cap[6]->LinkUsagePage = 0xFF01
339pp_data->cap[6]->LinkUsage = 0x0001
340pp_data->cap[6]->IsMultipleItemsForArray = 0
341pp_data->cap[6]->IsButtonCap = 1
342pp_data->cap[6]->IsPadding = 0
343pp_data->cap[6]->IsAbsolute = 1
344pp_data->cap[6]->IsRange = 0
345pp_data->cap[6]->IsAlias = 0
346pp_data->cap[6]->IsStringRange = 0
347pp_data->cap[6]->IsDesignatorRange = 0
348pp_data->cap[6]->Reserved1 = 0x000000
349pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
350pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
351pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
352pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
353pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
354pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
355pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
356pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
357pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
358pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
359pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
360pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
361pp_data->cap[6]->NotRange.Usage = 0x0002
362pp_data->cap[6]->NotRange.Reserved1 = 0x0002
363pp_data->cap[6]->NotRange.StringIndex = 0
364pp_data->cap[6]->NotRange.Reserved2 = 0
365pp_data->cap[6]->NotRange.DesignatorIndex = 0
366pp_data->cap[6]->NotRange.Reserved3 = 0
367pp_data->cap[6]->NotRange.DataIndex = 6
368pp_data->cap[6]->NotRange.Reserved4 = 6
369pp_data->cap[6]->Button.LogicalMin = 0
370pp_data->cap[6]->Button.LogicalMax = 0
371pp_data->cap[6]->Units = 0
372pp_data->cap[6]->UnitsExp = 0
373
374pp_data->cap[7]->UsagePage = 0xFF01
375pp_data->cap[7]->ReportID = 0x01
376pp_data->cap[7]->BitPosition = 4
377pp_data->cap[7]->BitSize = 1
378pp_data->cap[7]->ReportCount = 1
379pp_data->cap[7]->BytePosition = 0x0008
380pp_data->cap[7]->BitCount = 1
381pp_data->cap[7]->BitField = 0x02
382pp_data->cap[7]->NextBytePosition = 0x0009
383pp_data->cap[7]->LinkCollection = 0x0001
384pp_data->cap[7]->LinkUsagePage = 0xFF01
385pp_data->cap[7]->LinkUsage = 0x0001
386pp_data->cap[7]->IsMultipleItemsForArray = 0
387pp_data->cap[7]->IsButtonCap = 1
388pp_data->cap[7]->IsPadding = 0
389pp_data->cap[7]->IsAbsolute = 1
390pp_data->cap[7]->IsRange = 0
391pp_data->cap[7]->IsAlias = 0
392pp_data->cap[7]->IsStringRange = 0
393pp_data->cap[7]->IsDesignatorRange = 0
394pp_data->cap[7]->Reserved1 = 0x000000
395pp_data->cap[7]->pp_cap->UnknownTokens[0].Token = 0x00
396pp_data->cap[7]->pp_cap->UnknownTokens[0].Reserved = 0x000000
397pp_data->cap[7]->pp_cap->UnknownTokens[0].BitField = 0x00000000
398pp_data->cap[7]->pp_cap->UnknownTokens[1].Token = 0x00
399pp_data->cap[7]->pp_cap->UnknownTokens[1].Reserved = 0x000000
400pp_data->cap[7]->pp_cap->UnknownTokens[1].BitField = 0x00000000
401pp_data->cap[7]->pp_cap->UnknownTokens[2].Token = 0x00
402pp_data->cap[7]->pp_cap->UnknownTokens[2].Reserved = 0x000000
403pp_data->cap[7]->pp_cap->UnknownTokens[2].BitField = 0x00000000
404pp_data->cap[7]->pp_cap->UnknownTokens[3].Token = 0x00
405pp_data->cap[7]->pp_cap->UnknownTokens[3].Reserved = 0x000000
406pp_data->cap[7]->pp_cap->UnknownTokens[3].BitField = 0x00000000
407pp_data->cap[7]->NotRange.Usage = 0x0002
408pp_data->cap[7]->NotRange.Reserved1 = 0x0002
409pp_data->cap[7]->NotRange.StringIndex = 0
410pp_data->cap[7]->NotRange.Reserved2 = 0
411pp_data->cap[7]->NotRange.DesignatorIndex = 0
412pp_data->cap[7]->NotRange.Reserved3 = 0
413pp_data->cap[7]->NotRange.DataIndex = 7
414pp_data->cap[7]->NotRange.Reserved4 = 7
415pp_data->cap[7]->Button.LogicalMin = 0
416pp_data->cap[7]->Button.LogicalMax = 0
417pp_data->cap[7]->Units = 0
418pp_data->cap[7]->UnitsExp = 0
419
420pp_data->cap[8]->UsagePage = 0xFF01
421pp_data->cap[8]->ReportID = 0x01
422pp_data->cap[8]->BitPosition = 3
423pp_data->cap[8]->BitSize = 1
424pp_data->cap[8]->ReportCount = 1
425pp_data->cap[8]->BytePosition = 0x0008
426pp_data->cap[8]->BitCount = 1
427pp_data->cap[8]->BitField = 0x02
428pp_data->cap[8]->NextBytePosition = 0x0009
429pp_data->cap[8]->LinkCollection = 0x0001
430pp_data->cap[8]->LinkUsagePage = 0xFF01
431pp_data->cap[8]->LinkUsage = 0x0001
432pp_data->cap[8]->IsMultipleItemsForArray = 0
433pp_data->cap[8]->IsButtonCap = 1
434pp_data->cap[8]->IsPadding = 0
435pp_data->cap[8]->IsAbsolute = 1
436pp_data->cap[8]->IsRange = 0
437pp_data->cap[8]->IsAlias = 0
438pp_data->cap[8]->IsStringRange = 0
439pp_data->cap[8]->IsDesignatorRange = 0
440pp_data->cap[8]->Reserved1 = 0x000000
441pp_data->cap[8]->pp_cap->UnknownTokens[0].Token = 0x00
442pp_data->cap[8]->pp_cap->UnknownTokens[0].Reserved = 0x000000
443pp_data->cap[8]->pp_cap->UnknownTokens[0].BitField = 0x00000000
444pp_data->cap[8]->pp_cap->UnknownTokens[1].Token = 0x00
445pp_data->cap[8]->pp_cap->UnknownTokens[1].Reserved = 0x000000
446pp_data->cap[8]->pp_cap->UnknownTokens[1].BitField = 0x00000000
447pp_data->cap[8]->pp_cap->UnknownTokens[2].Token = 0x00
448pp_data->cap[8]->pp_cap->UnknownTokens[2].Reserved = 0x000000
449pp_data->cap[8]->pp_cap->UnknownTokens[2].BitField = 0x00000000
450pp_data->cap[8]->pp_cap->UnknownTokens[3].Token = 0x00
451pp_data->cap[8]->pp_cap->UnknownTokens[3].Reserved = 0x000000
452pp_data->cap[8]->pp_cap->UnknownTokens[3].BitField = 0x00000000
453pp_data->cap[8]->NotRange.Usage = 0x0002
454pp_data->cap[8]->NotRange.Reserved1 = 0x0002
455pp_data->cap[8]->NotRange.StringIndex = 0
456pp_data->cap[8]->NotRange.Reserved2 = 0
457pp_data->cap[8]->NotRange.DesignatorIndex = 0
458pp_data->cap[8]->NotRange.Reserved3 = 0
459pp_data->cap[8]->NotRange.DataIndex = 8
460pp_data->cap[8]->NotRange.Reserved4 = 8
461pp_data->cap[8]->Button.LogicalMin = 0
462pp_data->cap[8]->Button.LogicalMax = 0
463pp_data->cap[8]->Units = 0
464pp_data->cap[8]->UnitsExp = 0
465
466pp_data->cap[9]->UsagePage = 0xFF01
467pp_data->cap[9]->ReportID = 0x01
468pp_data->cap[9]->BitPosition = 2
469pp_data->cap[9]->BitSize = 1
470pp_data->cap[9]->ReportCount = 1
471pp_data->cap[9]->BytePosition = 0x0008
472pp_data->cap[9]->BitCount = 1
473pp_data->cap[9]->BitField = 0x02
474pp_data->cap[9]->NextBytePosition = 0x0009
475pp_data->cap[9]->LinkCollection = 0x0001
476pp_data->cap[9]->LinkUsagePage = 0xFF01
477pp_data->cap[9]->LinkUsage = 0x0001
478pp_data->cap[9]->IsMultipleItemsForArray = 0
479pp_data->cap[9]->IsButtonCap = 1
480pp_data->cap[9]->IsPadding = 0
481pp_data->cap[9]->IsAbsolute = 1
482pp_data->cap[9]->IsRange = 0
483pp_data->cap[9]->IsAlias = 0
484pp_data->cap[9]->IsStringRange = 0
485pp_data->cap[9]->IsDesignatorRange = 0
486pp_data->cap[9]->Reserved1 = 0x000000
487pp_data->cap[9]->pp_cap->UnknownTokens[0].Token = 0x00
488pp_data->cap[9]->pp_cap->UnknownTokens[0].Reserved = 0x000000
489pp_data->cap[9]->pp_cap->UnknownTokens[0].BitField = 0x00000000
490pp_data->cap[9]->pp_cap->UnknownTokens[1].Token = 0x00
491pp_data->cap[9]->pp_cap->UnknownTokens[1].Reserved = 0x000000
492pp_data->cap[9]->pp_cap->UnknownTokens[1].BitField = 0x00000000
493pp_data->cap[9]->pp_cap->UnknownTokens[2].Token = 0x00
494pp_data->cap[9]->pp_cap->UnknownTokens[2].Reserved = 0x000000
495pp_data->cap[9]->pp_cap->UnknownTokens[2].BitField = 0x00000000
496pp_data->cap[9]->pp_cap->UnknownTokens[3].Token = 0x00
497pp_data->cap[9]->pp_cap->UnknownTokens[3].Reserved = 0x000000
498pp_data->cap[9]->pp_cap->UnknownTokens[3].BitField = 0x00000000
499pp_data->cap[9]->NotRange.Usage = 0x0002
500pp_data->cap[9]->NotRange.Reserved1 = 0x0002
501pp_data->cap[9]->NotRange.StringIndex = 0
502pp_data->cap[9]->NotRange.Reserved2 = 0
503pp_data->cap[9]->NotRange.DesignatorIndex = 0
504pp_data->cap[9]->NotRange.Reserved3 = 0
505pp_data->cap[9]->NotRange.DataIndex = 9
506pp_data->cap[9]->NotRange.Reserved4 = 9
507pp_data->cap[9]->Button.LogicalMin = 0
508pp_data->cap[9]->Button.LogicalMax = 0
509pp_data->cap[9]->Units = 0
510pp_data->cap[9]->UnitsExp = 0
511
512pp_data->cap[10]->UsagePage = 0xFF01
513pp_data->cap[10]->ReportID = 0x01
514pp_data->cap[10]->BitPosition = 1
515pp_data->cap[10]->BitSize = 1
516pp_data->cap[10]->ReportCount = 1
517pp_data->cap[10]->BytePosition = 0x0008
518pp_data->cap[10]->BitCount = 1
519pp_data->cap[10]->BitField = 0x02
520pp_data->cap[10]->NextBytePosition = 0x0009
521pp_data->cap[10]->LinkCollection = 0x0001
522pp_data->cap[10]->LinkUsagePage = 0xFF01
523pp_data->cap[10]->LinkUsage = 0x0001
524pp_data->cap[10]->IsMultipleItemsForArray = 0
525pp_data->cap[10]->IsButtonCap = 1
526pp_data->cap[10]->IsPadding = 0
527pp_data->cap[10]->IsAbsolute = 1
528pp_data->cap[10]->IsRange = 0
529pp_data->cap[10]->IsAlias = 0
530pp_data->cap[10]->IsStringRange = 0
531pp_data->cap[10]->IsDesignatorRange = 0
532pp_data->cap[10]->Reserved1 = 0x000000
533pp_data->cap[10]->pp_cap->UnknownTokens[0].Token = 0x00
534pp_data->cap[10]->pp_cap->UnknownTokens[0].Reserved = 0x000000
535pp_data->cap[10]->pp_cap->UnknownTokens[0].BitField = 0x00000000
536pp_data->cap[10]->pp_cap->UnknownTokens[1].Token = 0x00
537pp_data->cap[10]->pp_cap->UnknownTokens[1].Reserved = 0x000000
538pp_data->cap[10]->pp_cap->UnknownTokens[1].BitField = 0x00000000
539pp_data->cap[10]->pp_cap->UnknownTokens[2].Token = 0x00
540pp_data->cap[10]->pp_cap->UnknownTokens[2].Reserved = 0x000000
541pp_data->cap[10]->pp_cap->UnknownTokens[2].BitField = 0x00000000
542pp_data->cap[10]->pp_cap->UnknownTokens[3].Token = 0x00
543pp_data->cap[10]->pp_cap->UnknownTokens[3].Reserved = 0x000000
544pp_data->cap[10]->pp_cap->UnknownTokens[3].BitField = 0x00000000
545pp_data->cap[10]->NotRange.Usage = 0x0002
546pp_data->cap[10]->NotRange.Reserved1 = 0x0002
547pp_data->cap[10]->NotRange.StringIndex = 0
548pp_data->cap[10]->NotRange.Reserved2 = 0
549pp_data->cap[10]->NotRange.DesignatorIndex = 0
550pp_data->cap[10]->NotRange.Reserved3 = 0
551pp_data->cap[10]->NotRange.DataIndex = 10
552pp_data->cap[10]->NotRange.Reserved4 = 10
553pp_data->cap[10]->Button.LogicalMin = 0
554pp_data->cap[10]->Button.LogicalMax = 0
555pp_data->cap[10]->Units = 0
556pp_data->cap[10]->UnitsExp = 0
557
558pp_data->cap[11]->UsagePage = 0xFF01
559pp_data->cap[11]->ReportID = 0x01
560pp_data->cap[11]->BitPosition = 0
561pp_data->cap[11]->BitSize = 1
562pp_data->cap[11]->ReportCount = 1
563pp_data->cap[11]->BytePosition = 0x0008
564pp_data->cap[11]->BitCount = 1
565pp_data->cap[11]->BitField = 0x02
566pp_data->cap[11]->NextBytePosition = 0x0009
567pp_data->cap[11]->LinkCollection = 0x0001
568pp_data->cap[11]->LinkUsagePage = 0xFF01
569pp_data->cap[11]->LinkUsage = 0x0001
570pp_data->cap[11]->IsMultipleItemsForArray = 0
571pp_data->cap[11]->IsButtonCap = 1
572pp_data->cap[11]->IsPadding = 0
573pp_data->cap[11]->IsAbsolute = 1
574pp_data->cap[11]->IsRange = 0
575pp_data->cap[11]->IsAlias = 0
576pp_data->cap[11]->IsStringRange = 0
577pp_data->cap[11]->IsDesignatorRange = 0
578pp_data->cap[11]->Reserved1 = 0x000000
579pp_data->cap[11]->pp_cap->UnknownTokens[0].Token = 0x00
580pp_data->cap[11]->pp_cap->UnknownTokens[0].Reserved = 0x000000
581pp_data->cap[11]->pp_cap->UnknownTokens[0].BitField = 0x00000000
582pp_data->cap[11]->pp_cap->UnknownTokens[1].Token = 0x00
583pp_data->cap[11]->pp_cap->UnknownTokens[1].Reserved = 0x000000
584pp_data->cap[11]->pp_cap->UnknownTokens[1].BitField = 0x00000000
585pp_data->cap[11]->pp_cap->UnknownTokens[2].Token = 0x00
586pp_data->cap[11]->pp_cap->UnknownTokens[2].Reserved = 0x000000
587pp_data->cap[11]->pp_cap->UnknownTokens[2].BitField = 0x00000000
588pp_data->cap[11]->pp_cap->UnknownTokens[3].Token = 0x00
589pp_data->cap[11]->pp_cap->UnknownTokens[3].Reserved = 0x000000
590pp_data->cap[11]->pp_cap->UnknownTokens[3].BitField = 0x00000000
591pp_data->cap[11]->NotRange.Usage = 0x0002
592pp_data->cap[11]->NotRange.Reserved1 = 0x0002
593pp_data->cap[11]->NotRange.StringIndex = 0
594pp_data->cap[11]->NotRange.Reserved2 = 0
595pp_data->cap[11]->NotRange.DesignatorIndex = 0
596pp_data->cap[11]->NotRange.Reserved3 = 0
597pp_data->cap[11]->NotRange.DataIndex = 11
598pp_data->cap[11]->NotRange.Reserved4 = 11
599pp_data->cap[11]->Button.LogicalMin = 0
600pp_data->cap[11]->Button.LogicalMax = 0
601pp_data->cap[11]->Units = 0
602pp_data->cap[11]->UnitsExp = 0
603
604pp_data->cap[12]->UsagePage = 0xFF01
605pp_data->cap[12]->ReportID = 0x01
606pp_data->cap[12]->BitPosition = 7
607pp_data->cap[12]->BitSize = 1
608pp_data->cap[12]->ReportCount = 1
609pp_data->cap[12]->BytePosition = 0x0007
610pp_data->cap[12]->BitCount = 1
611pp_data->cap[12]->BitField = 0x02
612pp_data->cap[12]->NextBytePosition = 0x0008
613pp_data->cap[12]->LinkCollection = 0x0001
614pp_data->cap[12]->LinkUsagePage = 0xFF01
615pp_data->cap[12]->LinkUsage = 0x0001
616pp_data->cap[12]->IsMultipleItemsForArray = 0
617pp_data->cap[12]->IsButtonCap = 1
618pp_data->cap[12]->IsPadding = 0
619pp_data->cap[12]->IsAbsolute = 1
620pp_data->cap[12]->IsRange = 0
621pp_data->cap[12]->IsAlias = 0
622pp_data->cap[12]->IsStringRange = 0
623pp_data->cap[12]->IsDesignatorRange = 0
624pp_data->cap[12]->Reserved1 = 0x000000
625pp_data->cap[12]->pp_cap->UnknownTokens[0].Token = 0x00
626pp_data->cap[12]->pp_cap->UnknownTokens[0].Reserved = 0x000000
627pp_data->cap[12]->pp_cap->UnknownTokens[0].BitField = 0x00000000
628pp_data->cap[12]->pp_cap->UnknownTokens[1].Token = 0x00
629pp_data->cap[12]->pp_cap->UnknownTokens[1].Reserved = 0x000000
630pp_data->cap[12]->pp_cap->UnknownTokens[1].BitField = 0x00000000
631pp_data->cap[12]->pp_cap->UnknownTokens[2].Token = 0x00
632pp_data->cap[12]->pp_cap->UnknownTokens[2].Reserved = 0x000000
633pp_data->cap[12]->pp_cap->UnknownTokens[2].BitField = 0x00000000
634pp_data->cap[12]->pp_cap->UnknownTokens[3].Token = 0x00
635pp_data->cap[12]->pp_cap->UnknownTokens[3].Reserved = 0x000000
636pp_data->cap[12]->pp_cap->UnknownTokens[3].BitField = 0x00000000
637pp_data->cap[12]->NotRange.Usage = 0x0002
638pp_data->cap[12]->NotRange.Reserved1 = 0x0002
639pp_data->cap[12]->NotRange.StringIndex = 0
640pp_data->cap[12]->NotRange.Reserved2 = 0
641pp_data->cap[12]->NotRange.DesignatorIndex = 0
642pp_data->cap[12]->NotRange.Reserved3 = 0
643pp_data->cap[12]->NotRange.DataIndex = 12
644pp_data->cap[12]->NotRange.Reserved4 = 12
645pp_data->cap[12]->Button.LogicalMin = 0
646pp_data->cap[12]->Button.LogicalMax = 0
647pp_data->cap[12]->Units = 0
648pp_data->cap[12]->UnitsExp = 0
649
650pp_data->cap[13]->UsagePage = 0xFF01
651pp_data->cap[13]->ReportID = 0x01
652pp_data->cap[13]->BitPosition = 6
653pp_data->cap[13]->BitSize = 1
654pp_data->cap[13]->ReportCount = 1
655pp_data->cap[13]->BytePosition = 0x0007
656pp_data->cap[13]->BitCount = 1
657pp_data->cap[13]->BitField = 0x02
658pp_data->cap[13]->NextBytePosition = 0x0008
659pp_data->cap[13]->LinkCollection = 0x0001
660pp_data->cap[13]->LinkUsagePage = 0xFF01
661pp_data->cap[13]->LinkUsage = 0x0001
662pp_data->cap[13]->IsMultipleItemsForArray = 0
663pp_data->cap[13]->IsButtonCap = 1
664pp_data->cap[13]->IsPadding = 0
665pp_data->cap[13]->IsAbsolute = 1
666pp_data->cap[13]->IsRange = 0
667pp_data->cap[13]->IsAlias = 0
668pp_data->cap[13]->IsStringRange = 0
669pp_data->cap[13]->IsDesignatorRange = 0
670pp_data->cap[13]->Reserved1 = 0x000000
671pp_data->cap[13]->pp_cap->UnknownTokens[0].Token = 0x00
672pp_data->cap[13]->pp_cap->UnknownTokens[0].Reserved = 0x000000
673pp_data->cap[13]->pp_cap->UnknownTokens[0].BitField = 0x00000000
674pp_data->cap[13]->pp_cap->UnknownTokens[1].Token = 0x00
675pp_data->cap[13]->pp_cap->UnknownTokens[1].Reserved = 0x000000
676pp_data->cap[13]->pp_cap->UnknownTokens[1].BitField = 0x00000000
677pp_data->cap[13]->pp_cap->UnknownTokens[2].Token = 0x00
678pp_data->cap[13]->pp_cap->UnknownTokens[2].Reserved = 0x000000
679pp_data->cap[13]->pp_cap->UnknownTokens[2].BitField = 0x00000000
680pp_data->cap[13]->pp_cap->UnknownTokens[3].Token = 0x00
681pp_data->cap[13]->pp_cap->UnknownTokens[3].Reserved = 0x000000
682pp_data->cap[13]->pp_cap->UnknownTokens[3].BitField = 0x00000000
683pp_data->cap[13]->NotRange.Usage = 0x0002
684pp_data->cap[13]->NotRange.Reserved1 = 0x0002
685pp_data->cap[13]->NotRange.StringIndex = 0
686pp_data->cap[13]->NotRange.Reserved2 = 0
687pp_data->cap[13]->NotRange.DesignatorIndex = 0
688pp_data->cap[13]->NotRange.Reserved3 = 0
689pp_data->cap[13]->NotRange.DataIndex = 13
690pp_data->cap[13]->NotRange.Reserved4 = 13
691pp_data->cap[13]->Button.LogicalMin = 0
692pp_data->cap[13]->Button.LogicalMax = 0
693pp_data->cap[13]->Units = 0
694pp_data->cap[13]->UnitsExp = 0
695
696pp_data->cap[14]->UsagePage = 0xFF01
697pp_data->cap[14]->ReportID = 0x01
698pp_data->cap[14]->BitPosition = 5
699pp_data->cap[14]->BitSize = 1
700pp_data->cap[14]->ReportCount = 1
701pp_data->cap[14]->BytePosition = 0x0007
702pp_data->cap[14]->BitCount = 1
703pp_data->cap[14]->BitField = 0x02
704pp_data->cap[14]->NextBytePosition = 0x0008
705pp_data->cap[14]->LinkCollection = 0x0001
706pp_data->cap[14]->LinkUsagePage = 0xFF01
707pp_data->cap[14]->LinkUsage = 0x0001
708pp_data->cap[14]->IsMultipleItemsForArray = 0
709pp_data->cap[14]->IsButtonCap = 1
710pp_data->cap[14]->IsPadding = 0
711pp_data->cap[14]->IsAbsolute = 1
712pp_data->cap[14]->IsRange = 0
713pp_data->cap[14]->IsAlias = 0
714pp_data->cap[14]->IsStringRange = 0
715pp_data->cap[14]->IsDesignatorRange = 0
716pp_data->cap[14]->Reserved1 = 0x000000
717pp_data->cap[14]->pp_cap->UnknownTokens[0].Token = 0x00
718pp_data->cap[14]->pp_cap->UnknownTokens[0].Reserved = 0x000000
719pp_data->cap[14]->pp_cap->UnknownTokens[0].BitField = 0x00000000
720pp_data->cap[14]->pp_cap->UnknownTokens[1].Token = 0x00
721pp_data->cap[14]->pp_cap->UnknownTokens[1].Reserved = 0x000000
722pp_data->cap[14]->pp_cap->UnknownTokens[1].BitField = 0x00000000
723pp_data->cap[14]->pp_cap->UnknownTokens[2].Token = 0x00
724pp_data->cap[14]->pp_cap->UnknownTokens[2].Reserved = 0x000000
725pp_data->cap[14]->pp_cap->UnknownTokens[2].BitField = 0x00000000
726pp_data->cap[14]->pp_cap->UnknownTokens[3].Token = 0x00
727pp_data->cap[14]->pp_cap->UnknownTokens[3].Reserved = 0x000000
728pp_data->cap[14]->pp_cap->UnknownTokens[3].BitField = 0x00000000
729pp_data->cap[14]->NotRange.Usage = 0x0002
730pp_data->cap[14]->NotRange.Reserved1 = 0x0002
731pp_data->cap[14]->NotRange.StringIndex = 0
732pp_data->cap[14]->NotRange.Reserved2 = 0
733pp_data->cap[14]->NotRange.DesignatorIndex = 0
734pp_data->cap[14]->NotRange.Reserved3 = 0
735pp_data->cap[14]->NotRange.DataIndex = 14
736pp_data->cap[14]->NotRange.Reserved4 = 14
737pp_data->cap[14]->Button.LogicalMin = 0
738pp_data->cap[14]->Button.LogicalMax = 0
739pp_data->cap[14]->Units = 0
740pp_data->cap[14]->UnitsExp = 0
741
742pp_data->cap[15]->UsagePage = 0xFF01
743pp_data->cap[15]->ReportID = 0x01
744pp_data->cap[15]->BitPosition = 4
745pp_data->cap[15]->BitSize = 1
746pp_data->cap[15]->ReportCount = 1
747pp_data->cap[15]->BytePosition = 0x0007
748pp_data->cap[15]->BitCount = 1
749pp_data->cap[15]->BitField = 0x02
750pp_data->cap[15]->NextBytePosition = 0x0008
751pp_data->cap[15]->LinkCollection = 0x0001
752pp_data->cap[15]->LinkUsagePage = 0xFF01
753pp_data->cap[15]->LinkUsage = 0x0001
754pp_data->cap[15]->IsMultipleItemsForArray = 0
755pp_data->cap[15]->IsButtonCap = 1
756pp_data->cap[15]->IsPadding = 0
757pp_data->cap[15]->IsAbsolute = 1
758pp_data->cap[15]->IsRange = 0
759pp_data->cap[15]->IsAlias = 0
760pp_data->cap[15]->IsStringRange = 0
761pp_data->cap[15]->IsDesignatorRange = 0
762pp_data->cap[15]->Reserved1 = 0x000000
763pp_data->cap[15]->pp_cap->UnknownTokens[0].Token = 0x00
764pp_data->cap[15]->pp_cap->UnknownTokens[0].Reserved = 0x000000
765pp_data->cap[15]->pp_cap->UnknownTokens[0].BitField = 0x00000000
766pp_data->cap[15]->pp_cap->UnknownTokens[1].Token = 0x00
767pp_data->cap[15]->pp_cap->UnknownTokens[1].Reserved = 0x000000
768pp_data->cap[15]->pp_cap->UnknownTokens[1].BitField = 0x00000000
769pp_data->cap[15]->pp_cap->UnknownTokens[2].Token = 0x00
770pp_data->cap[15]->pp_cap->UnknownTokens[2].Reserved = 0x000000
771pp_data->cap[15]->pp_cap->UnknownTokens[2].BitField = 0x00000000
772pp_data->cap[15]->pp_cap->UnknownTokens[3].Token = 0x00
773pp_data->cap[15]->pp_cap->UnknownTokens[3].Reserved = 0x000000
774pp_data->cap[15]->pp_cap->UnknownTokens[3].BitField = 0x00000000
775pp_data->cap[15]->NotRange.Usage = 0x0002
776pp_data->cap[15]->NotRange.Reserved1 = 0x0002
777pp_data->cap[15]->NotRange.StringIndex = 0
778pp_data->cap[15]->NotRange.Reserved2 = 0
779pp_data->cap[15]->NotRange.DesignatorIndex = 0
780pp_data->cap[15]->NotRange.Reserved3 = 0
781pp_data->cap[15]->NotRange.DataIndex = 15
782pp_data->cap[15]->NotRange.Reserved4 = 15
783pp_data->cap[15]->Button.LogicalMin = 0
784pp_data->cap[15]->Button.LogicalMax = 0
785pp_data->cap[15]->Units = 0
786pp_data->cap[15]->UnitsExp = 0
787
788pp_data->cap[16]->UsagePage = 0xFF01
789pp_data->cap[16]->ReportID = 0x01
790pp_data->cap[16]->BitPosition = 3
791pp_data->cap[16]->BitSize = 1
792pp_data->cap[16]->ReportCount = 1
793pp_data->cap[16]->BytePosition = 0x0007
794pp_data->cap[16]->BitCount = 1
795pp_data->cap[16]->BitField = 0x02
796pp_data->cap[16]->NextBytePosition = 0x0008
797pp_data->cap[16]->LinkCollection = 0x0001
798pp_data->cap[16]->LinkUsagePage = 0xFF01
799pp_data->cap[16]->LinkUsage = 0x0001
800pp_data->cap[16]->IsMultipleItemsForArray = 0
801pp_data->cap[16]->IsButtonCap = 1
802pp_data->cap[16]->IsPadding = 0
803pp_data->cap[16]->IsAbsolute = 1
804pp_data->cap[16]->IsRange = 0
805pp_data->cap[16]->IsAlias = 0
806pp_data->cap[16]->IsStringRange = 0
807pp_data->cap[16]->IsDesignatorRange = 0
808pp_data->cap[16]->Reserved1 = 0x000000
809pp_data->cap[16]->pp_cap->UnknownTokens[0].Token = 0x00
810pp_data->cap[16]->pp_cap->UnknownTokens[0].Reserved = 0x000000
811pp_data->cap[16]->pp_cap->UnknownTokens[0].BitField = 0x00000000
812pp_data->cap[16]->pp_cap->UnknownTokens[1].Token = 0x00
813pp_data->cap[16]->pp_cap->UnknownTokens[1].Reserved = 0x000000
814pp_data->cap[16]->pp_cap->UnknownTokens[1].BitField = 0x00000000
815pp_data->cap[16]->pp_cap->UnknownTokens[2].Token = 0x00
816pp_data->cap[16]->pp_cap->UnknownTokens[2].Reserved = 0x000000
817pp_data->cap[16]->pp_cap->UnknownTokens[2].BitField = 0x00000000
818pp_data->cap[16]->pp_cap->UnknownTokens[3].Token = 0x00
819pp_data->cap[16]->pp_cap->UnknownTokens[3].Reserved = 0x000000
820pp_data->cap[16]->pp_cap->UnknownTokens[3].BitField = 0x00000000
821pp_data->cap[16]->NotRange.Usage = 0x0002
822pp_data->cap[16]->NotRange.Reserved1 = 0x0002
823pp_data->cap[16]->NotRange.StringIndex = 0
824pp_data->cap[16]->NotRange.Reserved2 = 0
825pp_data->cap[16]->NotRange.DesignatorIndex = 0
826pp_data->cap[16]->NotRange.Reserved3 = 0
827pp_data->cap[16]->NotRange.DataIndex = 16
828pp_data->cap[16]->NotRange.Reserved4 = 16
829pp_data->cap[16]->Button.LogicalMin = 0
830pp_data->cap[16]->Button.LogicalMax = 0
831pp_data->cap[16]->Units = 0
832pp_data->cap[16]->UnitsExp = 0
833
834pp_data->cap[17]->UsagePage = 0xFF01
835pp_data->cap[17]->ReportID = 0x01
836pp_data->cap[17]->BitPosition = 2
837pp_data->cap[17]->BitSize = 1
838pp_data->cap[17]->ReportCount = 1
839pp_data->cap[17]->BytePosition = 0x0007
840pp_data->cap[17]->BitCount = 1
841pp_data->cap[17]->BitField = 0x02
842pp_data->cap[17]->NextBytePosition = 0x0008
843pp_data->cap[17]->LinkCollection = 0x0001
844pp_data->cap[17]->LinkUsagePage = 0xFF01
845pp_data->cap[17]->LinkUsage = 0x0001
846pp_data->cap[17]->IsMultipleItemsForArray = 0
847pp_data->cap[17]->IsButtonCap = 1
848pp_data->cap[17]->IsPadding = 0
849pp_data->cap[17]->IsAbsolute = 1
850pp_data->cap[17]->IsRange = 0
851pp_data->cap[17]->IsAlias = 0
852pp_data->cap[17]->IsStringRange = 0
853pp_data->cap[17]->IsDesignatorRange = 0
854pp_data->cap[17]->Reserved1 = 0x000000
855pp_data->cap[17]->pp_cap->UnknownTokens[0].Token = 0x00
856pp_data->cap[17]->pp_cap->UnknownTokens[0].Reserved = 0x000000
857pp_data->cap[17]->pp_cap->UnknownTokens[0].BitField = 0x00000000
858pp_data->cap[17]->pp_cap->UnknownTokens[1].Token = 0x00
859pp_data->cap[17]->pp_cap->UnknownTokens[1].Reserved = 0x000000
860pp_data->cap[17]->pp_cap->UnknownTokens[1].BitField = 0x00000000
861pp_data->cap[17]->pp_cap->UnknownTokens[2].Token = 0x00
862pp_data->cap[17]->pp_cap->UnknownTokens[2].Reserved = 0x000000
863pp_data->cap[17]->pp_cap->UnknownTokens[2].BitField = 0x00000000
864pp_data->cap[17]->pp_cap->UnknownTokens[3].Token = 0x00
865pp_data->cap[17]->pp_cap->UnknownTokens[3].Reserved = 0x000000
866pp_data->cap[17]->pp_cap->UnknownTokens[3].BitField = 0x00000000
867pp_data->cap[17]->NotRange.Usage = 0x0002
868pp_data->cap[17]->NotRange.Reserved1 = 0x0002
869pp_data->cap[17]->NotRange.StringIndex = 0
870pp_data->cap[17]->NotRange.Reserved2 = 0
871pp_data->cap[17]->NotRange.DesignatorIndex = 0
872pp_data->cap[17]->NotRange.Reserved3 = 0
873pp_data->cap[17]->NotRange.DataIndex = 17
874pp_data->cap[17]->NotRange.Reserved4 = 17
875pp_data->cap[17]->Button.LogicalMin = 0
876pp_data->cap[17]->Button.LogicalMax = 0
877pp_data->cap[17]->Units = 0
878pp_data->cap[17]->UnitsExp = 0
879
880pp_data->cap[18]->UsagePage = 0xFF01
881pp_data->cap[18]->ReportID = 0x01
882pp_data->cap[18]->BitPosition = 1
883pp_data->cap[18]->BitSize = 1
884pp_data->cap[18]->ReportCount = 1
885pp_data->cap[18]->BytePosition = 0x0007
886pp_data->cap[18]->BitCount = 1
887pp_data->cap[18]->BitField = 0x02
888pp_data->cap[18]->NextBytePosition = 0x0008
889pp_data->cap[18]->LinkCollection = 0x0001
890pp_data->cap[18]->LinkUsagePage = 0xFF01
891pp_data->cap[18]->LinkUsage = 0x0001
892pp_data->cap[18]->IsMultipleItemsForArray = 0
893pp_data->cap[18]->IsButtonCap = 1
894pp_data->cap[18]->IsPadding = 0
895pp_data->cap[18]->IsAbsolute = 1
896pp_data->cap[18]->IsRange = 0
897pp_data->cap[18]->IsAlias = 0
898pp_data->cap[18]->IsStringRange = 0
899pp_data->cap[18]->IsDesignatorRange = 0
900pp_data->cap[18]->Reserved1 = 0x000000
901pp_data->cap[18]->pp_cap->UnknownTokens[0].Token = 0x00
902pp_data->cap[18]->pp_cap->UnknownTokens[0].Reserved = 0x000000
903pp_data->cap[18]->pp_cap->UnknownTokens[0].BitField = 0x00000000
904pp_data->cap[18]->pp_cap->UnknownTokens[1].Token = 0x00
905pp_data->cap[18]->pp_cap->UnknownTokens[1].Reserved = 0x000000
906pp_data->cap[18]->pp_cap->UnknownTokens[1].BitField = 0x00000000
907pp_data->cap[18]->pp_cap->UnknownTokens[2].Token = 0x00
908pp_data->cap[18]->pp_cap->UnknownTokens[2].Reserved = 0x000000
909pp_data->cap[18]->pp_cap->UnknownTokens[2].BitField = 0x00000000
910pp_data->cap[18]->pp_cap->UnknownTokens[3].Token = 0x00
911pp_data->cap[18]->pp_cap->UnknownTokens[3].Reserved = 0x000000
912pp_data->cap[18]->pp_cap->UnknownTokens[3].BitField = 0x00000000
913pp_data->cap[18]->NotRange.Usage = 0x0002
914pp_data->cap[18]->NotRange.Reserved1 = 0x0002
915pp_data->cap[18]->NotRange.StringIndex = 0
916pp_data->cap[18]->NotRange.Reserved2 = 0
917pp_data->cap[18]->NotRange.DesignatorIndex = 0
918pp_data->cap[18]->NotRange.Reserved3 = 0
919pp_data->cap[18]->NotRange.DataIndex = 18
920pp_data->cap[18]->NotRange.Reserved4 = 18
921pp_data->cap[18]->Button.LogicalMin = 0
922pp_data->cap[18]->Button.LogicalMax = 0
923pp_data->cap[18]->Units = 0
924pp_data->cap[18]->UnitsExp = 0
925
926pp_data->cap[19]->UsagePage = 0xFF01
927pp_data->cap[19]->ReportID = 0x01
928pp_data->cap[19]->BitPosition = 0
929pp_data->cap[19]->BitSize = 1
930pp_data->cap[19]->ReportCount = 1
931pp_data->cap[19]->BytePosition = 0x0007
932pp_data->cap[19]->BitCount = 1
933pp_data->cap[19]->BitField = 0x02
934pp_data->cap[19]->NextBytePosition = 0x0008
935pp_data->cap[19]->LinkCollection = 0x0001
936pp_data->cap[19]->LinkUsagePage = 0xFF01
937pp_data->cap[19]->LinkUsage = 0x0001
938pp_data->cap[19]->IsMultipleItemsForArray = 0
939pp_data->cap[19]->IsButtonCap = 1
940pp_data->cap[19]->IsPadding = 0
941pp_data->cap[19]->IsAbsolute = 1
942pp_data->cap[19]->IsRange = 0
943pp_data->cap[19]->IsAlias = 0
944pp_data->cap[19]->IsStringRange = 0
945pp_data->cap[19]->IsDesignatorRange = 0
946pp_data->cap[19]->Reserved1 = 0x000000
947pp_data->cap[19]->pp_cap->UnknownTokens[0].Token = 0x00
948pp_data->cap[19]->pp_cap->UnknownTokens[0].Reserved = 0x000000
949pp_data->cap[19]->pp_cap->UnknownTokens[0].BitField = 0x00000000
950pp_data->cap[19]->pp_cap->UnknownTokens[1].Token = 0x00
951pp_data->cap[19]->pp_cap->UnknownTokens[1].Reserved = 0x000000
952pp_data->cap[19]->pp_cap->UnknownTokens[1].BitField = 0x00000000
953pp_data->cap[19]->pp_cap->UnknownTokens[2].Token = 0x00
954pp_data->cap[19]->pp_cap->UnknownTokens[2].Reserved = 0x000000
955pp_data->cap[19]->pp_cap->UnknownTokens[2].BitField = 0x00000000
956pp_data->cap[19]->pp_cap->UnknownTokens[3].Token = 0x00
957pp_data->cap[19]->pp_cap->UnknownTokens[3].Reserved = 0x000000
958pp_data->cap[19]->pp_cap->UnknownTokens[3].BitField = 0x00000000
959pp_data->cap[19]->NotRange.Usage = 0x0002
960pp_data->cap[19]->NotRange.Reserved1 = 0x0002
961pp_data->cap[19]->NotRange.StringIndex = 0
962pp_data->cap[19]->NotRange.Reserved2 = 0
963pp_data->cap[19]->NotRange.DesignatorIndex = 0
964pp_data->cap[19]->NotRange.Reserved3 = 0
965pp_data->cap[19]->NotRange.DataIndex = 19
966pp_data->cap[19]->NotRange.Reserved4 = 19
967pp_data->cap[19]->Button.LogicalMin = 0
968pp_data->cap[19]->Button.LogicalMax = 0
969pp_data->cap[19]->Units = 0
970pp_data->cap[19]->UnitsExp = 0
971
972pp_data->cap[20]->UsagePage = 0xFF01
973pp_data->cap[20]->ReportID = 0x01
974pp_data->cap[20]->BitPosition = 7
975pp_data->cap[20]->BitSize = 1
976pp_data->cap[20]->ReportCount = 1
977pp_data->cap[20]->BytePosition = 0x0006
978pp_data->cap[20]->BitCount = 1
979pp_data->cap[20]->BitField = 0x02
980pp_data->cap[20]->NextBytePosition = 0x0007
981pp_data->cap[20]->LinkCollection = 0x0001
982pp_data->cap[20]->LinkUsagePage = 0xFF01
983pp_data->cap[20]->LinkUsage = 0x0001
984pp_data->cap[20]->IsMultipleItemsForArray = 0
985pp_data->cap[20]->IsButtonCap = 1
986pp_data->cap[20]->IsPadding = 0
987pp_data->cap[20]->IsAbsolute = 1
988pp_data->cap[20]->IsRange = 0
989pp_data->cap[20]->IsAlias = 0
990pp_data->cap[20]->IsStringRange = 0
991pp_data->cap[20]->IsDesignatorRange = 0
992pp_data->cap[20]->Reserved1 = 0x000000
993pp_data->cap[20]->pp_cap->UnknownTokens[0].Token = 0x00
994pp_data->cap[20]->pp_cap->UnknownTokens[0].Reserved = 0x000000
995pp_data->cap[20]->pp_cap->UnknownTokens[0].BitField = 0x00000000
996pp_data->cap[20]->pp_cap->UnknownTokens[1].Token = 0x00
997pp_data->cap[20]->pp_cap->UnknownTokens[1].Reserved = 0x000000
998pp_data->cap[20]->pp_cap->UnknownTokens[1].BitField = 0x00000000
999pp_data->cap[20]->pp_cap->UnknownTokens[2].Token = 0x00
1000pp_data->cap[20]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1001pp_data->cap[20]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1002pp_data->cap[20]->pp_cap->UnknownTokens[3].Token = 0x00
1003pp_data->cap[20]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1004pp_data->cap[20]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1005pp_data->cap[20]->NotRange.Usage = 0x0002
1006pp_data->cap[20]->NotRange.Reserved1 = 0x0002
1007pp_data->cap[20]->NotRange.StringIndex = 0
1008pp_data->cap[20]->NotRange.Reserved2 = 0
1009pp_data->cap[20]->NotRange.DesignatorIndex = 0
1010pp_data->cap[20]->NotRange.Reserved3 = 0
1011pp_data->cap[20]->NotRange.DataIndex = 20
1012pp_data->cap[20]->NotRange.Reserved4 = 20
1013pp_data->cap[20]->Button.LogicalMin = 0
1014pp_data->cap[20]->Button.LogicalMax = 0
1015pp_data->cap[20]->Units = 0
1016pp_data->cap[20]->UnitsExp = 0
1017
1018pp_data->cap[21]->UsagePage = 0xFF01
1019pp_data->cap[21]->ReportID = 0x01
1020pp_data->cap[21]->BitPosition = 6
1021pp_data->cap[21]->BitSize = 1
1022pp_data->cap[21]->ReportCount = 1
1023pp_data->cap[21]->BytePosition = 0x0006
1024pp_data->cap[21]->BitCount = 1
1025pp_data->cap[21]->BitField = 0x02
1026pp_data->cap[21]->NextBytePosition = 0x0007
1027pp_data->cap[21]->LinkCollection = 0x0001
1028pp_data->cap[21]->LinkUsagePage = 0xFF01
1029pp_data->cap[21]->LinkUsage = 0x0001
1030pp_data->cap[21]->IsMultipleItemsForArray = 0
1031pp_data->cap[21]->IsButtonCap = 1
1032pp_data->cap[21]->IsPadding = 0
1033pp_data->cap[21]->IsAbsolute = 1
1034pp_data->cap[21]->IsRange = 0
1035pp_data->cap[21]->IsAlias = 0
1036pp_data->cap[21]->IsStringRange = 0
1037pp_data->cap[21]->IsDesignatorRange = 0
1038pp_data->cap[21]->Reserved1 = 0x000000
1039pp_data->cap[21]->pp_cap->UnknownTokens[0].Token = 0x00
1040pp_data->cap[21]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1041pp_data->cap[21]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1042pp_data->cap[21]->pp_cap->UnknownTokens[1].Token = 0x00
1043pp_data->cap[21]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1044pp_data->cap[21]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1045pp_data->cap[21]->pp_cap->UnknownTokens[2].Token = 0x00
1046pp_data->cap[21]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1047pp_data->cap[21]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1048pp_data->cap[21]->pp_cap->UnknownTokens[3].Token = 0x00
1049pp_data->cap[21]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1050pp_data->cap[21]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1051pp_data->cap[21]->NotRange.Usage = 0x0002
1052pp_data->cap[21]->NotRange.Reserved1 = 0x0002
1053pp_data->cap[21]->NotRange.StringIndex = 0
1054pp_data->cap[21]->NotRange.Reserved2 = 0
1055pp_data->cap[21]->NotRange.DesignatorIndex = 0
1056pp_data->cap[21]->NotRange.Reserved3 = 0
1057pp_data->cap[21]->NotRange.DataIndex = 21
1058pp_data->cap[21]->NotRange.Reserved4 = 21
1059pp_data->cap[21]->Button.LogicalMin = 0
1060pp_data->cap[21]->Button.LogicalMax = 0
1061pp_data->cap[21]->Units = 0
1062pp_data->cap[21]->UnitsExp = 0
1063
1064pp_data->cap[22]->UsagePage = 0xFF01
1065pp_data->cap[22]->ReportID = 0x01
1066pp_data->cap[22]->BitPosition = 5
1067pp_data->cap[22]->BitSize = 1
1068pp_data->cap[22]->ReportCount = 1
1069pp_data->cap[22]->BytePosition = 0x0006
1070pp_data->cap[22]->BitCount = 1
1071pp_data->cap[22]->BitField = 0x02
1072pp_data->cap[22]->NextBytePosition = 0x0007
1073pp_data->cap[22]->LinkCollection = 0x0001
1074pp_data->cap[22]->LinkUsagePage = 0xFF01
1075pp_data->cap[22]->LinkUsage = 0x0001
1076pp_data->cap[22]->IsMultipleItemsForArray = 0
1077pp_data->cap[22]->IsButtonCap = 1
1078pp_data->cap[22]->IsPadding = 0
1079pp_data->cap[22]->IsAbsolute = 1
1080pp_data->cap[22]->IsRange = 0
1081pp_data->cap[22]->IsAlias = 0
1082pp_data->cap[22]->IsStringRange = 0
1083pp_data->cap[22]->IsDesignatorRange = 0
1084pp_data->cap[22]->Reserved1 = 0x000000
1085pp_data->cap[22]->pp_cap->UnknownTokens[0].Token = 0x00
1086pp_data->cap[22]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1087pp_data->cap[22]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1088pp_data->cap[22]->pp_cap->UnknownTokens[1].Token = 0x00
1089pp_data->cap[22]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1090pp_data->cap[22]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1091pp_data->cap[22]->pp_cap->UnknownTokens[2].Token = 0x00
1092pp_data->cap[22]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1093pp_data->cap[22]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1094pp_data->cap[22]->pp_cap->UnknownTokens[3].Token = 0x00
1095pp_data->cap[22]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1096pp_data->cap[22]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1097pp_data->cap[22]->NotRange.Usage = 0x0002
1098pp_data->cap[22]->NotRange.Reserved1 = 0x0002
1099pp_data->cap[22]->NotRange.StringIndex = 0
1100pp_data->cap[22]->NotRange.Reserved2 = 0
1101pp_data->cap[22]->NotRange.DesignatorIndex = 0
1102pp_data->cap[22]->NotRange.Reserved3 = 0
1103pp_data->cap[22]->NotRange.DataIndex = 22
1104pp_data->cap[22]->NotRange.Reserved4 = 22
1105pp_data->cap[22]->Button.LogicalMin = 0
1106pp_data->cap[22]->Button.LogicalMax = 0
1107pp_data->cap[22]->Units = 0
1108pp_data->cap[22]->UnitsExp = 0
1109
1110pp_data->cap[23]->UsagePage = 0xFF01
1111pp_data->cap[23]->ReportID = 0x01
1112pp_data->cap[23]->BitPosition = 4
1113pp_data->cap[23]->BitSize = 1
1114pp_data->cap[23]->ReportCount = 1
1115pp_data->cap[23]->BytePosition = 0x0006
1116pp_data->cap[23]->BitCount = 1
1117pp_data->cap[23]->BitField = 0x02
1118pp_data->cap[23]->NextBytePosition = 0x0007
1119pp_data->cap[23]->LinkCollection = 0x0001
1120pp_data->cap[23]->LinkUsagePage = 0xFF01
1121pp_data->cap[23]->LinkUsage = 0x0001
1122pp_data->cap[23]->IsMultipleItemsForArray = 0
1123pp_data->cap[23]->IsButtonCap = 1
1124pp_data->cap[23]->IsPadding = 0
1125pp_data->cap[23]->IsAbsolute = 1
1126pp_data->cap[23]->IsRange = 0
1127pp_data->cap[23]->IsAlias = 0
1128pp_data->cap[23]->IsStringRange = 0
1129pp_data->cap[23]->IsDesignatorRange = 0
1130pp_data->cap[23]->Reserved1 = 0x000000
1131pp_data->cap[23]->pp_cap->UnknownTokens[0].Token = 0x00
1132pp_data->cap[23]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1133pp_data->cap[23]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1134pp_data->cap[23]->pp_cap->UnknownTokens[1].Token = 0x00
1135pp_data->cap[23]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1136pp_data->cap[23]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1137pp_data->cap[23]->pp_cap->UnknownTokens[2].Token = 0x00
1138pp_data->cap[23]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1139pp_data->cap[23]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1140pp_data->cap[23]->pp_cap->UnknownTokens[3].Token = 0x00
1141pp_data->cap[23]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1142pp_data->cap[23]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1143pp_data->cap[23]->NotRange.Usage = 0x0002
1144pp_data->cap[23]->NotRange.Reserved1 = 0x0002
1145pp_data->cap[23]->NotRange.StringIndex = 0
1146pp_data->cap[23]->NotRange.Reserved2 = 0
1147pp_data->cap[23]->NotRange.DesignatorIndex = 0
1148pp_data->cap[23]->NotRange.Reserved3 = 0
1149pp_data->cap[23]->NotRange.DataIndex = 23
1150pp_data->cap[23]->NotRange.Reserved4 = 23
1151pp_data->cap[23]->Button.LogicalMin = 0
1152pp_data->cap[23]->Button.LogicalMax = 0
1153pp_data->cap[23]->Units = 0
1154pp_data->cap[23]->UnitsExp = 0
1155
1156pp_data->cap[24]->UsagePage = 0xFF01
1157pp_data->cap[24]->ReportID = 0x01
1158pp_data->cap[24]->BitPosition = 3
1159pp_data->cap[24]->BitSize = 1
1160pp_data->cap[24]->ReportCount = 1
1161pp_data->cap[24]->BytePosition = 0x0006
1162pp_data->cap[24]->BitCount = 1
1163pp_data->cap[24]->BitField = 0x02
1164pp_data->cap[24]->NextBytePosition = 0x0007
1165pp_data->cap[24]->LinkCollection = 0x0001
1166pp_data->cap[24]->LinkUsagePage = 0xFF01
1167pp_data->cap[24]->LinkUsage = 0x0001
1168pp_data->cap[24]->IsMultipleItemsForArray = 0
1169pp_data->cap[24]->IsButtonCap = 1
1170pp_data->cap[24]->IsPadding = 0
1171pp_data->cap[24]->IsAbsolute = 1
1172pp_data->cap[24]->IsRange = 0
1173pp_data->cap[24]->IsAlias = 0
1174pp_data->cap[24]->IsStringRange = 0
1175pp_data->cap[24]->IsDesignatorRange = 0
1176pp_data->cap[24]->Reserved1 = 0x000000
1177pp_data->cap[24]->pp_cap->UnknownTokens[0].Token = 0x00
1178pp_data->cap[24]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1179pp_data->cap[24]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1180pp_data->cap[24]->pp_cap->UnknownTokens[1].Token = 0x00
1181pp_data->cap[24]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1182pp_data->cap[24]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1183pp_data->cap[24]->pp_cap->UnknownTokens[2].Token = 0x00
1184pp_data->cap[24]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1185pp_data->cap[24]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1186pp_data->cap[24]->pp_cap->UnknownTokens[3].Token = 0x00
1187pp_data->cap[24]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1188pp_data->cap[24]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1189pp_data->cap[24]->NotRange.Usage = 0x0002
1190pp_data->cap[24]->NotRange.Reserved1 = 0x0002
1191pp_data->cap[24]->NotRange.StringIndex = 0
1192pp_data->cap[24]->NotRange.Reserved2 = 0
1193pp_data->cap[24]->NotRange.DesignatorIndex = 0
1194pp_data->cap[24]->NotRange.Reserved3 = 0
1195pp_data->cap[24]->NotRange.DataIndex = 24
1196pp_data->cap[24]->NotRange.Reserved4 = 24
1197pp_data->cap[24]->Button.LogicalMin = 0
1198pp_data->cap[24]->Button.LogicalMax = 0
1199pp_data->cap[24]->Units = 0
1200pp_data->cap[24]->UnitsExp = 0
1201
1202pp_data->cap[25]->UsagePage = 0xFF01
1203pp_data->cap[25]->ReportID = 0x01
1204pp_data->cap[25]->BitPosition = 2
1205pp_data->cap[25]->BitSize = 1
1206pp_data->cap[25]->ReportCount = 1
1207pp_data->cap[25]->BytePosition = 0x0006
1208pp_data->cap[25]->BitCount = 1
1209pp_data->cap[25]->BitField = 0x02
1210pp_data->cap[25]->NextBytePosition = 0x0007
1211pp_data->cap[25]->LinkCollection = 0x0001
1212pp_data->cap[25]->LinkUsagePage = 0xFF01
1213pp_data->cap[25]->LinkUsage = 0x0001
1214pp_data->cap[25]->IsMultipleItemsForArray = 0
1215pp_data->cap[25]->IsButtonCap = 1
1216pp_data->cap[25]->IsPadding = 0
1217pp_data->cap[25]->IsAbsolute = 1
1218pp_data->cap[25]->IsRange = 0
1219pp_data->cap[25]->IsAlias = 0
1220pp_data->cap[25]->IsStringRange = 0
1221pp_data->cap[25]->IsDesignatorRange = 0
1222pp_data->cap[25]->Reserved1 = 0x000000
1223pp_data->cap[25]->pp_cap->UnknownTokens[0].Token = 0x00
1224pp_data->cap[25]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1225pp_data->cap[25]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1226pp_data->cap[25]->pp_cap->UnknownTokens[1].Token = 0x00
1227pp_data->cap[25]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1228pp_data->cap[25]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1229pp_data->cap[25]->pp_cap->UnknownTokens[2].Token = 0x00
1230pp_data->cap[25]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1231pp_data->cap[25]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1232pp_data->cap[25]->pp_cap->UnknownTokens[3].Token = 0x00
1233pp_data->cap[25]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1234pp_data->cap[25]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1235pp_data->cap[25]->NotRange.Usage = 0x0002
1236pp_data->cap[25]->NotRange.Reserved1 = 0x0002
1237pp_data->cap[25]->NotRange.StringIndex = 0
1238pp_data->cap[25]->NotRange.Reserved2 = 0
1239pp_data->cap[25]->NotRange.DesignatorIndex = 0
1240pp_data->cap[25]->NotRange.Reserved3 = 0
1241pp_data->cap[25]->NotRange.DataIndex = 25
1242pp_data->cap[25]->NotRange.Reserved4 = 25
1243pp_data->cap[25]->Button.LogicalMin = 0
1244pp_data->cap[25]->Button.LogicalMax = 0
1245pp_data->cap[25]->Units = 0
1246pp_data->cap[25]->UnitsExp = 0
1247
1248pp_data->cap[26]->UsagePage = 0xFF01
1249pp_data->cap[26]->ReportID = 0x01
1250pp_data->cap[26]->BitPosition = 1
1251pp_data->cap[26]->BitSize = 1
1252pp_data->cap[26]->ReportCount = 1
1253pp_data->cap[26]->BytePosition = 0x0006
1254pp_data->cap[26]->BitCount = 1
1255pp_data->cap[26]->BitField = 0x02
1256pp_data->cap[26]->NextBytePosition = 0x0007
1257pp_data->cap[26]->LinkCollection = 0x0001
1258pp_data->cap[26]->LinkUsagePage = 0xFF01
1259pp_data->cap[26]->LinkUsage = 0x0001
1260pp_data->cap[26]->IsMultipleItemsForArray = 0
1261pp_data->cap[26]->IsButtonCap = 1
1262pp_data->cap[26]->IsPadding = 0
1263pp_data->cap[26]->IsAbsolute = 1
1264pp_data->cap[26]->IsRange = 0
1265pp_data->cap[26]->IsAlias = 0
1266pp_data->cap[26]->IsStringRange = 0
1267pp_data->cap[26]->IsDesignatorRange = 0
1268pp_data->cap[26]->Reserved1 = 0x000000
1269pp_data->cap[26]->pp_cap->UnknownTokens[0].Token = 0x00
1270pp_data->cap[26]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1271pp_data->cap[26]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1272pp_data->cap[26]->pp_cap->UnknownTokens[1].Token = 0x00
1273pp_data->cap[26]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1274pp_data->cap[26]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1275pp_data->cap[26]->pp_cap->UnknownTokens[2].Token = 0x00
1276pp_data->cap[26]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1277pp_data->cap[26]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1278pp_data->cap[26]->pp_cap->UnknownTokens[3].Token = 0x00
1279pp_data->cap[26]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1280pp_data->cap[26]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1281pp_data->cap[26]->NotRange.Usage = 0x0002
1282pp_data->cap[26]->NotRange.Reserved1 = 0x0002
1283pp_data->cap[26]->NotRange.StringIndex = 0
1284pp_data->cap[26]->NotRange.Reserved2 = 0
1285pp_data->cap[26]->NotRange.DesignatorIndex = 0
1286pp_data->cap[26]->NotRange.Reserved3 = 0
1287pp_data->cap[26]->NotRange.DataIndex = 26
1288pp_data->cap[26]->NotRange.Reserved4 = 26
1289pp_data->cap[26]->Button.LogicalMin = 0
1290pp_data->cap[26]->Button.LogicalMax = 0
1291pp_data->cap[26]->Units = 0
1292pp_data->cap[26]->UnitsExp = 0
1293
1294pp_data->cap[27]->UsagePage = 0xFF01
1295pp_data->cap[27]->ReportID = 0x01
1296pp_data->cap[27]->BitPosition = 0
1297pp_data->cap[27]->BitSize = 1
1298pp_data->cap[27]->ReportCount = 1
1299pp_data->cap[27]->BytePosition = 0x0006
1300pp_data->cap[27]->BitCount = 1
1301pp_data->cap[27]->BitField = 0x02
1302pp_data->cap[27]->NextBytePosition = 0x0007
1303pp_data->cap[27]->LinkCollection = 0x0001
1304pp_data->cap[27]->LinkUsagePage = 0xFF01
1305pp_data->cap[27]->LinkUsage = 0x0001
1306pp_data->cap[27]->IsMultipleItemsForArray = 0
1307pp_data->cap[27]->IsButtonCap = 1
1308pp_data->cap[27]->IsPadding = 0
1309pp_data->cap[27]->IsAbsolute = 1
1310pp_data->cap[27]->IsRange = 0
1311pp_data->cap[27]->IsAlias = 0
1312pp_data->cap[27]->IsStringRange = 0
1313pp_data->cap[27]->IsDesignatorRange = 0
1314pp_data->cap[27]->Reserved1 = 0x000000
1315pp_data->cap[27]->pp_cap->UnknownTokens[0].Token = 0x00
1316pp_data->cap[27]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1317pp_data->cap[27]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1318pp_data->cap[27]->pp_cap->UnknownTokens[1].Token = 0x00
1319pp_data->cap[27]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1320pp_data->cap[27]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1321pp_data->cap[27]->pp_cap->UnknownTokens[2].Token = 0x00
1322pp_data->cap[27]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1323pp_data->cap[27]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1324pp_data->cap[27]->pp_cap->UnknownTokens[3].Token = 0x00
1325pp_data->cap[27]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1326pp_data->cap[27]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1327pp_data->cap[27]->NotRange.Usage = 0x0002
1328pp_data->cap[27]->NotRange.Reserved1 = 0x0002
1329pp_data->cap[27]->NotRange.StringIndex = 0
1330pp_data->cap[27]->NotRange.Reserved2 = 0
1331pp_data->cap[27]->NotRange.DesignatorIndex = 0
1332pp_data->cap[27]->NotRange.Reserved3 = 0
1333pp_data->cap[27]->NotRange.DataIndex = 27
1334pp_data->cap[27]->NotRange.Reserved4 = 27
1335pp_data->cap[27]->Button.LogicalMin = 0
1336pp_data->cap[27]->Button.LogicalMax = 0
1337pp_data->cap[27]->Units = 0
1338pp_data->cap[27]->UnitsExp = 0
1339
1340pp_data->cap[28]->UsagePage = 0xFF01
1341pp_data->cap[28]->ReportID = 0x01
1342pp_data->cap[28]->BitPosition = 7
1343pp_data->cap[28]->BitSize = 1
1344pp_data->cap[28]->ReportCount = 1
1345pp_data->cap[28]->BytePosition = 0x0005
1346pp_data->cap[28]->BitCount = 1
1347pp_data->cap[28]->BitField = 0x02
1348pp_data->cap[28]->NextBytePosition = 0x0006
1349pp_data->cap[28]->LinkCollection = 0x0001
1350pp_data->cap[28]->LinkUsagePage = 0xFF01
1351pp_data->cap[28]->LinkUsage = 0x0001
1352pp_data->cap[28]->IsMultipleItemsForArray = 0
1353pp_data->cap[28]->IsButtonCap = 1
1354pp_data->cap[28]->IsPadding = 0
1355pp_data->cap[28]->IsAbsolute = 1
1356pp_data->cap[28]->IsRange = 0
1357pp_data->cap[28]->IsAlias = 0
1358pp_data->cap[28]->IsStringRange = 0
1359pp_data->cap[28]->IsDesignatorRange = 0
1360pp_data->cap[28]->Reserved1 = 0x000000
1361pp_data->cap[28]->pp_cap->UnknownTokens[0].Token = 0x00
1362pp_data->cap[28]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1363pp_data->cap[28]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1364pp_data->cap[28]->pp_cap->UnknownTokens[1].Token = 0x00
1365pp_data->cap[28]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1366pp_data->cap[28]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1367pp_data->cap[28]->pp_cap->UnknownTokens[2].Token = 0x00
1368pp_data->cap[28]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1369pp_data->cap[28]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1370pp_data->cap[28]->pp_cap->UnknownTokens[3].Token = 0x00
1371pp_data->cap[28]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1372pp_data->cap[28]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1373pp_data->cap[28]->NotRange.Usage = 0x0002
1374pp_data->cap[28]->NotRange.Reserved1 = 0x0002
1375pp_data->cap[28]->NotRange.StringIndex = 0
1376pp_data->cap[28]->NotRange.Reserved2 = 0
1377pp_data->cap[28]->NotRange.DesignatorIndex = 0
1378pp_data->cap[28]->NotRange.Reserved3 = 0
1379pp_data->cap[28]->NotRange.DataIndex = 28
1380pp_data->cap[28]->NotRange.Reserved4 = 28
1381pp_data->cap[28]->Button.LogicalMin = 0
1382pp_data->cap[28]->Button.LogicalMax = 0
1383pp_data->cap[28]->Units = 0
1384pp_data->cap[28]->UnitsExp = 0
1385
1386pp_data->cap[29]->UsagePage = 0xFF01
1387pp_data->cap[29]->ReportID = 0x01
1388pp_data->cap[29]->BitPosition = 6
1389pp_data->cap[29]->BitSize = 1
1390pp_data->cap[29]->ReportCount = 1
1391pp_data->cap[29]->BytePosition = 0x0005
1392pp_data->cap[29]->BitCount = 1
1393pp_data->cap[29]->BitField = 0x02
1394pp_data->cap[29]->NextBytePosition = 0x0006
1395pp_data->cap[29]->LinkCollection = 0x0001
1396pp_data->cap[29]->LinkUsagePage = 0xFF01
1397pp_data->cap[29]->LinkUsage = 0x0001
1398pp_data->cap[29]->IsMultipleItemsForArray = 0
1399pp_data->cap[29]->IsButtonCap = 1
1400pp_data->cap[29]->IsPadding = 0
1401pp_data->cap[29]->IsAbsolute = 1
1402pp_data->cap[29]->IsRange = 0
1403pp_data->cap[29]->IsAlias = 0
1404pp_data->cap[29]->IsStringRange = 0
1405pp_data->cap[29]->IsDesignatorRange = 0
1406pp_data->cap[29]->Reserved1 = 0x000000
1407pp_data->cap[29]->pp_cap->UnknownTokens[0].Token = 0x00
1408pp_data->cap[29]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1409pp_data->cap[29]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1410pp_data->cap[29]->pp_cap->UnknownTokens[1].Token = 0x00
1411pp_data->cap[29]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1412pp_data->cap[29]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1413pp_data->cap[29]->pp_cap->UnknownTokens[2].Token = 0x00
1414pp_data->cap[29]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1415pp_data->cap[29]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1416pp_data->cap[29]->pp_cap->UnknownTokens[3].Token = 0x00
1417pp_data->cap[29]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1418pp_data->cap[29]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1419pp_data->cap[29]->NotRange.Usage = 0x0002
1420pp_data->cap[29]->NotRange.Reserved1 = 0x0002
1421pp_data->cap[29]->NotRange.StringIndex = 0
1422pp_data->cap[29]->NotRange.Reserved2 = 0
1423pp_data->cap[29]->NotRange.DesignatorIndex = 0
1424pp_data->cap[29]->NotRange.Reserved3 = 0
1425pp_data->cap[29]->NotRange.DataIndex = 29
1426pp_data->cap[29]->NotRange.Reserved4 = 29
1427pp_data->cap[29]->Button.LogicalMin = 0
1428pp_data->cap[29]->Button.LogicalMax = 0
1429pp_data->cap[29]->Units = 0
1430pp_data->cap[29]->UnitsExp = 0
1431
1432pp_data->cap[30]->UsagePage = 0xFF01
1433pp_data->cap[30]->ReportID = 0x01
1434pp_data->cap[30]->BitPosition = 5
1435pp_data->cap[30]->BitSize = 1
1436pp_data->cap[30]->ReportCount = 1
1437pp_data->cap[30]->BytePosition = 0x0005
1438pp_data->cap[30]->BitCount = 1
1439pp_data->cap[30]->BitField = 0x02
1440pp_data->cap[30]->NextBytePosition = 0x0006
1441pp_data->cap[30]->LinkCollection = 0x0001
1442pp_data->cap[30]->LinkUsagePage = 0xFF01
1443pp_data->cap[30]->LinkUsage = 0x0001
1444pp_data->cap[30]->IsMultipleItemsForArray = 0
1445pp_data->cap[30]->IsButtonCap = 1
1446pp_data->cap[30]->IsPadding = 0
1447pp_data->cap[30]->IsAbsolute = 1
1448pp_data->cap[30]->IsRange = 0
1449pp_data->cap[30]->IsAlias = 0
1450pp_data->cap[30]->IsStringRange = 0
1451pp_data->cap[30]->IsDesignatorRange = 0
1452pp_data->cap[30]->Reserved1 = 0x000000
1453pp_data->cap[30]->pp_cap->UnknownTokens[0].Token = 0x00
1454pp_data->cap[30]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1455pp_data->cap[30]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1456pp_data->cap[30]->pp_cap->UnknownTokens[1].Token = 0x00
1457pp_data->cap[30]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1458pp_data->cap[30]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1459pp_data->cap[30]->pp_cap->UnknownTokens[2].Token = 0x00
1460pp_data->cap[30]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1461pp_data->cap[30]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1462pp_data->cap[30]->pp_cap->UnknownTokens[3].Token = 0x00
1463pp_data->cap[30]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1464pp_data->cap[30]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1465pp_data->cap[30]->NotRange.Usage = 0x0002
1466pp_data->cap[30]->NotRange.Reserved1 = 0x0002
1467pp_data->cap[30]->NotRange.StringIndex = 0
1468pp_data->cap[30]->NotRange.Reserved2 = 0
1469pp_data->cap[30]->NotRange.DesignatorIndex = 0
1470pp_data->cap[30]->NotRange.Reserved3 = 0
1471pp_data->cap[30]->NotRange.DataIndex = 30
1472pp_data->cap[30]->NotRange.Reserved4 = 30
1473pp_data->cap[30]->Button.LogicalMin = 0
1474pp_data->cap[30]->Button.LogicalMax = 0
1475pp_data->cap[30]->Units = 0
1476pp_data->cap[30]->UnitsExp = 0
1477
1478pp_data->cap[31]->UsagePage = 0xFF01
1479pp_data->cap[31]->ReportID = 0x01
1480pp_data->cap[31]->BitPosition = 4
1481pp_data->cap[31]->BitSize = 1
1482pp_data->cap[31]->ReportCount = 1
1483pp_data->cap[31]->BytePosition = 0x0005
1484pp_data->cap[31]->BitCount = 1
1485pp_data->cap[31]->BitField = 0x02
1486pp_data->cap[31]->NextBytePosition = 0x0006
1487pp_data->cap[31]->LinkCollection = 0x0001
1488pp_data->cap[31]->LinkUsagePage = 0xFF01
1489pp_data->cap[31]->LinkUsage = 0x0001
1490pp_data->cap[31]->IsMultipleItemsForArray = 0
1491pp_data->cap[31]->IsButtonCap = 1
1492pp_data->cap[31]->IsPadding = 0
1493pp_data->cap[31]->IsAbsolute = 1
1494pp_data->cap[31]->IsRange = 0
1495pp_data->cap[31]->IsAlias = 0
1496pp_data->cap[31]->IsStringRange = 0
1497pp_data->cap[31]->IsDesignatorRange = 0
1498pp_data->cap[31]->Reserved1 = 0x000000
1499pp_data->cap[31]->pp_cap->UnknownTokens[0].Token = 0x00
1500pp_data->cap[31]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1501pp_data->cap[31]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1502pp_data->cap[31]->pp_cap->UnknownTokens[1].Token = 0x00
1503pp_data->cap[31]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1504pp_data->cap[31]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1505pp_data->cap[31]->pp_cap->UnknownTokens[2].Token = 0x00
1506pp_data->cap[31]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1507pp_data->cap[31]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1508pp_data->cap[31]->pp_cap->UnknownTokens[3].Token = 0x00
1509pp_data->cap[31]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1510pp_data->cap[31]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1511pp_data->cap[31]->NotRange.Usage = 0x0002
1512pp_data->cap[31]->NotRange.Reserved1 = 0x0002
1513pp_data->cap[31]->NotRange.StringIndex = 0
1514pp_data->cap[31]->NotRange.Reserved2 = 0
1515pp_data->cap[31]->NotRange.DesignatorIndex = 0
1516pp_data->cap[31]->NotRange.Reserved3 = 0
1517pp_data->cap[31]->NotRange.DataIndex = 31
1518pp_data->cap[31]->NotRange.Reserved4 = 31
1519pp_data->cap[31]->Button.LogicalMin = 0
1520pp_data->cap[31]->Button.LogicalMax = 0
1521pp_data->cap[31]->Units = 0
1522pp_data->cap[31]->UnitsExp = 0
1523
1524pp_data->cap[32]->UsagePage = 0xFF01
1525pp_data->cap[32]->ReportID = 0x01
1526pp_data->cap[32]->BitPosition = 3
1527pp_data->cap[32]->BitSize = 1
1528pp_data->cap[32]->ReportCount = 1
1529pp_data->cap[32]->BytePosition = 0x0005
1530pp_data->cap[32]->BitCount = 1
1531pp_data->cap[32]->BitField = 0x02
1532pp_data->cap[32]->NextBytePosition = 0x0006
1533pp_data->cap[32]->LinkCollection = 0x0001
1534pp_data->cap[32]->LinkUsagePage = 0xFF01
1535pp_data->cap[32]->LinkUsage = 0x0001
1536pp_data->cap[32]->IsMultipleItemsForArray = 0
1537pp_data->cap[32]->IsButtonCap = 1
1538pp_data->cap[32]->IsPadding = 0
1539pp_data->cap[32]->IsAbsolute = 1
1540pp_data->cap[32]->IsRange = 0
1541pp_data->cap[32]->IsAlias = 0
1542pp_data->cap[32]->IsStringRange = 0
1543pp_data->cap[32]->IsDesignatorRange = 0
1544pp_data->cap[32]->Reserved1 = 0x000000
1545pp_data->cap[32]->pp_cap->UnknownTokens[0].Token = 0x00
1546pp_data->cap[32]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1547pp_data->cap[32]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1548pp_data->cap[32]->pp_cap->UnknownTokens[1].Token = 0x00
1549pp_data->cap[32]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1550pp_data->cap[32]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1551pp_data->cap[32]->pp_cap->UnknownTokens[2].Token = 0x00
1552pp_data->cap[32]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1553pp_data->cap[32]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1554pp_data->cap[32]->pp_cap->UnknownTokens[3].Token = 0x00
1555pp_data->cap[32]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1556pp_data->cap[32]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1557pp_data->cap[32]->NotRange.Usage = 0x0002
1558pp_data->cap[32]->NotRange.Reserved1 = 0x0002
1559pp_data->cap[32]->NotRange.StringIndex = 0
1560pp_data->cap[32]->NotRange.Reserved2 = 0
1561pp_data->cap[32]->NotRange.DesignatorIndex = 0
1562pp_data->cap[32]->NotRange.Reserved3 = 0
1563pp_data->cap[32]->NotRange.DataIndex = 32
1564pp_data->cap[32]->NotRange.Reserved4 = 32
1565pp_data->cap[32]->Button.LogicalMin = 0
1566pp_data->cap[32]->Button.LogicalMax = 0
1567pp_data->cap[32]->Units = 0
1568pp_data->cap[32]->UnitsExp = 0
1569
1570pp_data->cap[33]->UsagePage = 0xFF01
1571pp_data->cap[33]->ReportID = 0x01
1572pp_data->cap[33]->BitPosition = 2
1573pp_data->cap[33]->BitSize = 1
1574pp_data->cap[33]->ReportCount = 1
1575pp_data->cap[33]->BytePosition = 0x0005
1576pp_data->cap[33]->BitCount = 1
1577pp_data->cap[33]->BitField = 0x02
1578pp_data->cap[33]->NextBytePosition = 0x0006
1579pp_data->cap[33]->LinkCollection = 0x0001
1580pp_data->cap[33]->LinkUsagePage = 0xFF01
1581pp_data->cap[33]->LinkUsage = 0x0001
1582pp_data->cap[33]->IsMultipleItemsForArray = 0
1583pp_data->cap[33]->IsButtonCap = 1
1584pp_data->cap[33]->IsPadding = 0
1585pp_data->cap[33]->IsAbsolute = 1
1586pp_data->cap[33]->IsRange = 0
1587pp_data->cap[33]->IsAlias = 0
1588pp_data->cap[33]->IsStringRange = 0
1589pp_data->cap[33]->IsDesignatorRange = 0
1590pp_data->cap[33]->Reserved1 = 0x000000
1591pp_data->cap[33]->pp_cap->UnknownTokens[0].Token = 0x00
1592pp_data->cap[33]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1593pp_data->cap[33]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1594pp_data->cap[33]->pp_cap->UnknownTokens[1].Token = 0x00
1595pp_data->cap[33]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1596pp_data->cap[33]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1597pp_data->cap[33]->pp_cap->UnknownTokens[2].Token = 0x00
1598pp_data->cap[33]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1599pp_data->cap[33]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1600pp_data->cap[33]->pp_cap->UnknownTokens[3].Token = 0x00
1601pp_data->cap[33]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1602pp_data->cap[33]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1603pp_data->cap[33]->NotRange.Usage = 0x0002
1604pp_data->cap[33]->NotRange.Reserved1 = 0x0002
1605pp_data->cap[33]->NotRange.StringIndex = 0
1606pp_data->cap[33]->NotRange.Reserved2 = 0
1607pp_data->cap[33]->NotRange.DesignatorIndex = 0
1608pp_data->cap[33]->NotRange.Reserved3 = 0
1609pp_data->cap[33]->NotRange.DataIndex = 33
1610pp_data->cap[33]->NotRange.Reserved4 = 33
1611pp_data->cap[33]->Button.LogicalMin = 0
1612pp_data->cap[33]->Button.LogicalMax = 0
1613pp_data->cap[33]->Units = 0
1614pp_data->cap[33]->UnitsExp = 0
1615
1616pp_data->cap[34]->UsagePage = 0xFF01
1617pp_data->cap[34]->ReportID = 0x01
1618pp_data->cap[34]->BitPosition = 1
1619pp_data->cap[34]->BitSize = 1
1620pp_data->cap[34]->ReportCount = 1
1621pp_data->cap[34]->BytePosition = 0x0005
1622pp_data->cap[34]->BitCount = 1
1623pp_data->cap[34]->BitField = 0x02
1624pp_data->cap[34]->NextBytePosition = 0x0006
1625pp_data->cap[34]->LinkCollection = 0x0001
1626pp_data->cap[34]->LinkUsagePage = 0xFF01
1627pp_data->cap[34]->LinkUsage = 0x0001
1628pp_data->cap[34]->IsMultipleItemsForArray = 0
1629pp_data->cap[34]->IsButtonCap = 1
1630pp_data->cap[34]->IsPadding = 0
1631pp_data->cap[34]->IsAbsolute = 1
1632pp_data->cap[34]->IsRange = 0
1633pp_data->cap[34]->IsAlias = 0
1634pp_data->cap[34]->IsStringRange = 0
1635pp_data->cap[34]->IsDesignatorRange = 0
1636pp_data->cap[34]->Reserved1 = 0x000000
1637pp_data->cap[34]->pp_cap->UnknownTokens[0].Token = 0x00
1638pp_data->cap[34]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1639pp_data->cap[34]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1640pp_data->cap[34]->pp_cap->UnknownTokens[1].Token = 0x00
1641pp_data->cap[34]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1642pp_data->cap[34]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1643pp_data->cap[34]->pp_cap->UnknownTokens[2].Token = 0x00
1644pp_data->cap[34]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1645pp_data->cap[34]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1646pp_data->cap[34]->pp_cap->UnknownTokens[3].Token = 0x00
1647pp_data->cap[34]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1648pp_data->cap[34]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1649pp_data->cap[34]->NotRange.Usage = 0x0002
1650pp_data->cap[34]->NotRange.Reserved1 = 0x0002
1651pp_data->cap[34]->NotRange.StringIndex = 0
1652pp_data->cap[34]->NotRange.Reserved2 = 0
1653pp_data->cap[34]->NotRange.DesignatorIndex = 0
1654pp_data->cap[34]->NotRange.Reserved3 = 0
1655pp_data->cap[34]->NotRange.DataIndex = 34
1656pp_data->cap[34]->NotRange.Reserved4 = 34
1657pp_data->cap[34]->Button.LogicalMin = 0
1658pp_data->cap[34]->Button.LogicalMax = 0
1659pp_data->cap[34]->Units = 0
1660pp_data->cap[34]->UnitsExp = 0
1661
1662pp_data->cap[35]->UsagePage = 0xFF01
1663pp_data->cap[35]->ReportID = 0x01
1664pp_data->cap[35]->BitPosition = 0
1665pp_data->cap[35]->BitSize = 1
1666pp_data->cap[35]->ReportCount = 1
1667pp_data->cap[35]->BytePosition = 0x0005
1668pp_data->cap[35]->BitCount = 1
1669pp_data->cap[35]->BitField = 0x02
1670pp_data->cap[35]->NextBytePosition = 0x0006
1671pp_data->cap[35]->LinkCollection = 0x0001
1672pp_data->cap[35]->LinkUsagePage = 0xFF01
1673pp_data->cap[35]->LinkUsage = 0x0001
1674pp_data->cap[35]->IsMultipleItemsForArray = 0
1675pp_data->cap[35]->IsButtonCap = 1
1676pp_data->cap[35]->IsPadding = 0
1677pp_data->cap[35]->IsAbsolute = 1
1678pp_data->cap[35]->IsRange = 0
1679pp_data->cap[35]->IsAlias = 0
1680pp_data->cap[35]->IsStringRange = 0
1681pp_data->cap[35]->IsDesignatorRange = 0
1682pp_data->cap[35]->Reserved1 = 0x000000
1683pp_data->cap[35]->pp_cap->UnknownTokens[0].Token = 0x00
1684pp_data->cap[35]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1685pp_data->cap[35]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1686pp_data->cap[35]->pp_cap->UnknownTokens[1].Token = 0x00
1687pp_data->cap[35]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1688pp_data->cap[35]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1689pp_data->cap[35]->pp_cap->UnknownTokens[2].Token = 0x00
1690pp_data->cap[35]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1691pp_data->cap[35]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1692pp_data->cap[35]->pp_cap->UnknownTokens[3].Token = 0x00
1693pp_data->cap[35]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1694pp_data->cap[35]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1695pp_data->cap[35]->NotRange.Usage = 0x0002
1696pp_data->cap[35]->NotRange.Reserved1 = 0x0002
1697pp_data->cap[35]->NotRange.StringIndex = 0
1698pp_data->cap[35]->NotRange.Reserved2 = 0
1699pp_data->cap[35]->NotRange.DesignatorIndex = 0
1700pp_data->cap[35]->NotRange.Reserved3 = 0
1701pp_data->cap[35]->NotRange.DataIndex = 35
1702pp_data->cap[35]->NotRange.Reserved4 = 35
1703pp_data->cap[35]->Button.LogicalMin = 0
1704pp_data->cap[35]->Button.LogicalMax = 0
1705pp_data->cap[35]->Units = 0
1706pp_data->cap[35]->UnitsExp = 0
1707
1708pp_data->cap[36]->UsagePage = 0xFF01
1709pp_data->cap[36]->ReportID = 0x01
1710pp_data->cap[36]->BitPosition = 7
1711pp_data->cap[36]->BitSize = 1
1712pp_data->cap[36]->ReportCount = 1
1713pp_data->cap[36]->BytePosition = 0x0004
1714pp_data->cap[36]->BitCount = 1
1715pp_data->cap[36]->BitField = 0x02
1716pp_data->cap[36]->NextBytePosition = 0x0005
1717pp_data->cap[36]->LinkCollection = 0x0001
1718pp_data->cap[36]->LinkUsagePage = 0xFF01
1719pp_data->cap[36]->LinkUsage = 0x0001
1720pp_data->cap[36]->IsMultipleItemsForArray = 0
1721pp_data->cap[36]->IsButtonCap = 1
1722pp_data->cap[36]->IsPadding = 0
1723pp_data->cap[36]->IsAbsolute = 1
1724pp_data->cap[36]->IsRange = 0
1725pp_data->cap[36]->IsAlias = 0
1726pp_data->cap[36]->IsStringRange = 0
1727pp_data->cap[36]->IsDesignatorRange = 0
1728pp_data->cap[36]->Reserved1 = 0x000000
1729pp_data->cap[36]->pp_cap->UnknownTokens[0].Token = 0x00
1730pp_data->cap[36]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1731pp_data->cap[36]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1732pp_data->cap[36]->pp_cap->UnknownTokens[1].Token = 0x00
1733pp_data->cap[36]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1734pp_data->cap[36]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1735pp_data->cap[36]->pp_cap->UnknownTokens[2].Token = 0x00
1736pp_data->cap[36]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1737pp_data->cap[36]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1738pp_data->cap[36]->pp_cap->UnknownTokens[3].Token = 0x00
1739pp_data->cap[36]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1740pp_data->cap[36]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1741pp_data->cap[36]->NotRange.Usage = 0x0002
1742pp_data->cap[36]->NotRange.Reserved1 = 0x0002
1743pp_data->cap[36]->NotRange.StringIndex = 0
1744pp_data->cap[36]->NotRange.Reserved2 = 0
1745pp_data->cap[36]->NotRange.DesignatorIndex = 0
1746pp_data->cap[36]->NotRange.Reserved3 = 0
1747pp_data->cap[36]->NotRange.DataIndex = 36
1748pp_data->cap[36]->NotRange.Reserved4 = 36
1749pp_data->cap[36]->Button.LogicalMin = 0
1750pp_data->cap[36]->Button.LogicalMax = 0
1751pp_data->cap[36]->Units = 0
1752pp_data->cap[36]->UnitsExp = 0
1753
1754pp_data->cap[37]->UsagePage = 0xFF01
1755pp_data->cap[37]->ReportID = 0x01
1756pp_data->cap[37]->BitPosition = 6
1757pp_data->cap[37]->BitSize = 1
1758pp_data->cap[37]->ReportCount = 1
1759pp_data->cap[37]->BytePosition = 0x0004
1760pp_data->cap[37]->BitCount = 1
1761pp_data->cap[37]->BitField = 0x02
1762pp_data->cap[37]->NextBytePosition = 0x0005
1763pp_data->cap[37]->LinkCollection = 0x0001
1764pp_data->cap[37]->LinkUsagePage = 0xFF01
1765pp_data->cap[37]->LinkUsage = 0x0001
1766pp_data->cap[37]->IsMultipleItemsForArray = 0
1767pp_data->cap[37]->IsButtonCap = 1
1768pp_data->cap[37]->IsPadding = 0
1769pp_data->cap[37]->IsAbsolute = 1
1770pp_data->cap[37]->IsRange = 0
1771pp_data->cap[37]->IsAlias = 0
1772pp_data->cap[37]->IsStringRange = 0
1773pp_data->cap[37]->IsDesignatorRange = 0
1774pp_data->cap[37]->Reserved1 = 0x000000
1775pp_data->cap[37]->pp_cap->UnknownTokens[0].Token = 0x00
1776pp_data->cap[37]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1777pp_data->cap[37]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1778pp_data->cap[37]->pp_cap->UnknownTokens[1].Token = 0x00
1779pp_data->cap[37]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1780pp_data->cap[37]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1781pp_data->cap[37]->pp_cap->UnknownTokens[2].Token = 0x00
1782pp_data->cap[37]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1783pp_data->cap[37]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1784pp_data->cap[37]->pp_cap->UnknownTokens[3].Token = 0x00
1785pp_data->cap[37]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1786pp_data->cap[37]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1787pp_data->cap[37]->NotRange.Usage = 0x0002
1788pp_data->cap[37]->NotRange.Reserved1 = 0x0002
1789pp_data->cap[37]->NotRange.StringIndex = 0
1790pp_data->cap[37]->NotRange.Reserved2 = 0
1791pp_data->cap[37]->NotRange.DesignatorIndex = 0
1792pp_data->cap[37]->NotRange.Reserved3 = 0
1793pp_data->cap[37]->NotRange.DataIndex = 37
1794pp_data->cap[37]->NotRange.Reserved4 = 37
1795pp_data->cap[37]->Button.LogicalMin = 0
1796pp_data->cap[37]->Button.LogicalMax = 0
1797pp_data->cap[37]->Units = 0
1798pp_data->cap[37]->UnitsExp = 0
1799
1800pp_data->cap[38]->UsagePage = 0xFF01
1801pp_data->cap[38]->ReportID = 0x01
1802pp_data->cap[38]->BitPosition = 5
1803pp_data->cap[38]->BitSize = 1
1804pp_data->cap[38]->ReportCount = 1
1805pp_data->cap[38]->BytePosition = 0x0004
1806pp_data->cap[38]->BitCount = 1
1807pp_data->cap[38]->BitField = 0x02
1808pp_data->cap[38]->NextBytePosition = 0x0005
1809pp_data->cap[38]->LinkCollection = 0x0001
1810pp_data->cap[38]->LinkUsagePage = 0xFF01
1811pp_data->cap[38]->LinkUsage = 0x0001
1812pp_data->cap[38]->IsMultipleItemsForArray = 0
1813pp_data->cap[38]->IsButtonCap = 1
1814pp_data->cap[38]->IsPadding = 0
1815pp_data->cap[38]->IsAbsolute = 1
1816pp_data->cap[38]->IsRange = 0
1817pp_data->cap[38]->IsAlias = 0
1818pp_data->cap[38]->IsStringRange = 0
1819pp_data->cap[38]->IsDesignatorRange = 0
1820pp_data->cap[38]->Reserved1 = 0x000000
1821pp_data->cap[38]->pp_cap->UnknownTokens[0].Token = 0x00
1822pp_data->cap[38]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1823pp_data->cap[38]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1824pp_data->cap[38]->pp_cap->UnknownTokens[1].Token = 0x00
1825pp_data->cap[38]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1826pp_data->cap[38]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1827pp_data->cap[38]->pp_cap->UnknownTokens[2].Token = 0x00
1828pp_data->cap[38]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1829pp_data->cap[38]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1830pp_data->cap[38]->pp_cap->UnknownTokens[3].Token = 0x00
1831pp_data->cap[38]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1832pp_data->cap[38]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1833pp_data->cap[38]->NotRange.Usage = 0x0002
1834pp_data->cap[38]->NotRange.Reserved1 = 0x0002
1835pp_data->cap[38]->NotRange.StringIndex = 0
1836pp_data->cap[38]->NotRange.Reserved2 = 0
1837pp_data->cap[38]->NotRange.DesignatorIndex = 0
1838pp_data->cap[38]->NotRange.Reserved3 = 0
1839pp_data->cap[38]->NotRange.DataIndex = 38
1840pp_data->cap[38]->NotRange.Reserved4 = 38
1841pp_data->cap[38]->Button.LogicalMin = 0
1842pp_data->cap[38]->Button.LogicalMax = 0
1843pp_data->cap[38]->Units = 0
1844pp_data->cap[38]->UnitsExp = 0
1845
1846pp_data->cap[39]->UsagePage = 0xFF01
1847pp_data->cap[39]->ReportID = 0x01
1848pp_data->cap[39]->BitPosition = 4
1849pp_data->cap[39]->BitSize = 1
1850pp_data->cap[39]->ReportCount = 1
1851pp_data->cap[39]->BytePosition = 0x0004
1852pp_data->cap[39]->BitCount = 1
1853pp_data->cap[39]->BitField = 0x02
1854pp_data->cap[39]->NextBytePosition = 0x0005
1855pp_data->cap[39]->LinkCollection = 0x0001
1856pp_data->cap[39]->LinkUsagePage = 0xFF01
1857pp_data->cap[39]->LinkUsage = 0x0001
1858pp_data->cap[39]->IsMultipleItemsForArray = 0
1859pp_data->cap[39]->IsButtonCap = 1
1860pp_data->cap[39]->IsPadding = 0
1861pp_data->cap[39]->IsAbsolute = 1
1862pp_data->cap[39]->IsRange = 0
1863pp_data->cap[39]->IsAlias = 0
1864pp_data->cap[39]->IsStringRange = 0
1865pp_data->cap[39]->IsDesignatorRange = 0
1866pp_data->cap[39]->Reserved1 = 0x000000
1867pp_data->cap[39]->pp_cap->UnknownTokens[0].Token = 0x00
1868pp_data->cap[39]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1869pp_data->cap[39]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1870pp_data->cap[39]->pp_cap->UnknownTokens[1].Token = 0x00
1871pp_data->cap[39]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1872pp_data->cap[39]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1873pp_data->cap[39]->pp_cap->UnknownTokens[2].Token = 0x00
1874pp_data->cap[39]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1875pp_data->cap[39]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1876pp_data->cap[39]->pp_cap->UnknownTokens[3].Token = 0x00
1877pp_data->cap[39]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1878pp_data->cap[39]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1879pp_data->cap[39]->NotRange.Usage = 0x0002
1880pp_data->cap[39]->NotRange.Reserved1 = 0x0002
1881pp_data->cap[39]->NotRange.StringIndex = 0
1882pp_data->cap[39]->NotRange.Reserved2 = 0
1883pp_data->cap[39]->NotRange.DesignatorIndex = 0
1884pp_data->cap[39]->NotRange.Reserved3 = 0
1885pp_data->cap[39]->NotRange.DataIndex = 39
1886pp_data->cap[39]->NotRange.Reserved4 = 39
1887pp_data->cap[39]->Button.LogicalMin = 0
1888pp_data->cap[39]->Button.LogicalMax = 0
1889pp_data->cap[39]->Units = 0
1890pp_data->cap[39]->UnitsExp = 0
1891
1892pp_data->cap[40]->UsagePage = 0xFF01
1893pp_data->cap[40]->ReportID = 0x01
1894pp_data->cap[40]->BitPosition = 3
1895pp_data->cap[40]->BitSize = 1
1896pp_data->cap[40]->ReportCount = 1
1897pp_data->cap[40]->BytePosition = 0x0004
1898pp_data->cap[40]->BitCount = 1
1899pp_data->cap[40]->BitField = 0x02
1900pp_data->cap[40]->NextBytePosition = 0x0005
1901pp_data->cap[40]->LinkCollection = 0x0001
1902pp_data->cap[40]->LinkUsagePage = 0xFF01
1903pp_data->cap[40]->LinkUsage = 0x0001
1904pp_data->cap[40]->IsMultipleItemsForArray = 0
1905pp_data->cap[40]->IsButtonCap = 1
1906pp_data->cap[40]->IsPadding = 0
1907pp_data->cap[40]->IsAbsolute = 1
1908pp_data->cap[40]->IsRange = 0
1909pp_data->cap[40]->IsAlias = 0
1910pp_data->cap[40]->IsStringRange = 0
1911pp_data->cap[40]->IsDesignatorRange = 0
1912pp_data->cap[40]->Reserved1 = 0x000000
1913pp_data->cap[40]->pp_cap->UnknownTokens[0].Token = 0x00
1914pp_data->cap[40]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1915pp_data->cap[40]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1916pp_data->cap[40]->pp_cap->UnknownTokens[1].Token = 0x00
1917pp_data->cap[40]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1918pp_data->cap[40]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1919pp_data->cap[40]->pp_cap->UnknownTokens[2].Token = 0x00
1920pp_data->cap[40]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1921pp_data->cap[40]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1922pp_data->cap[40]->pp_cap->UnknownTokens[3].Token = 0x00
1923pp_data->cap[40]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1924pp_data->cap[40]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1925pp_data->cap[40]->NotRange.Usage = 0x0002
1926pp_data->cap[40]->NotRange.Reserved1 = 0x0002
1927pp_data->cap[40]->NotRange.StringIndex = 0
1928pp_data->cap[40]->NotRange.Reserved2 = 0
1929pp_data->cap[40]->NotRange.DesignatorIndex = 0
1930pp_data->cap[40]->NotRange.Reserved3 = 0
1931pp_data->cap[40]->NotRange.DataIndex = 40
1932pp_data->cap[40]->NotRange.Reserved4 = 40
1933pp_data->cap[40]->Button.LogicalMin = 0
1934pp_data->cap[40]->Button.LogicalMax = 0
1935pp_data->cap[40]->Units = 0
1936pp_data->cap[40]->UnitsExp = 0
1937
1938pp_data->cap[41]->UsagePage = 0xFF01
1939pp_data->cap[41]->ReportID = 0x01
1940pp_data->cap[41]->BitPosition = 2
1941pp_data->cap[41]->BitSize = 1
1942pp_data->cap[41]->ReportCount = 1
1943pp_data->cap[41]->BytePosition = 0x0004
1944pp_data->cap[41]->BitCount = 1
1945pp_data->cap[41]->BitField = 0x02
1946pp_data->cap[41]->NextBytePosition = 0x0005
1947pp_data->cap[41]->LinkCollection = 0x0001
1948pp_data->cap[41]->LinkUsagePage = 0xFF01
1949pp_data->cap[41]->LinkUsage = 0x0001
1950pp_data->cap[41]->IsMultipleItemsForArray = 0
1951pp_data->cap[41]->IsButtonCap = 1
1952pp_data->cap[41]->IsPadding = 0
1953pp_data->cap[41]->IsAbsolute = 1
1954pp_data->cap[41]->IsRange = 0
1955pp_data->cap[41]->IsAlias = 0
1956pp_data->cap[41]->IsStringRange = 0
1957pp_data->cap[41]->IsDesignatorRange = 0
1958pp_data->cap[41]->Reserved1 = 0x000000
1959pp_data->cap[41]->pp_cap->UnknownTokens[0].Token = 0x00
1960pp_data->cap[41]->pp_cap->UnknownTokens[0].Reserved = 0x000000
1961pp_data->cap[41]->pp_cap->UnknownTokens[0].BitField = 0x00000000
1962pp_data->cap[41]->pp_cap->UnknownTokens[1].Token = 0x00
1963pp_data->cap[41]->pp_cap->UnknownTokens[1].Reserved = 0x000000
1964pp_data->cap[41]->pp_cap->UnknownTokens[1].BitField = 0x00000000
1965pp_data->cap[41]->pp_cap->UnknownTokens[2].Token = 0x00
1966pp_data->cap[41]->pp_cap->UnknownTokens[2].Reserved = 0x000000
1967pp_data->cap[41]->pp_cap->UnknownTokens[2].BitField = 0x00000000
1968pp_data->cap[41]->pp_cap->UnknownTokens[3].Token = 0x00
1969pp_data->cap[41]->pp_cap->UnknownTokens[3].Reserved = 0x000000
1970pp_data->cap[41]->pp_cap->UnknownTokens[3].BitField = 0x00000000
1971pp_data->cap[41]->NotRange.Usage = 0x0002
1972pp_data->cap[41]->NotRange.Reserved1 = 0x0002
1973pp_data->cap[41]->NotRange.StringIndex = 0
1974pp_data->cap[41]->NotRange.Reserved2 = 0
1975pp_data->cap[41]->NotRange.DesignatorIndex = 0
1976pp_data->cap[41]->NotRange.Reserved3 = 0
1977pp_data->cap[41]->NotRange.DataIndex = 41
1978pp_data->cap[41]->NotRange.Reserved4 = 41
1979pp_data->cap[41]->Button.LogicalMin = 0
1980pp_data->cap[41]->Button.LogicalMax = 0
1981pp_data->cap[41]->Units = 0
1982pp_data->cap[41]->UnitsExp = 0
1983
1984pp_data->cap[42]->UsagePage = 0xFF01
1985pp_data->cap[42]->ReportID = 0x01
1986pp_data->cap[42]->BitPosition = 1
1987pp_data->cap[42]->BitSize = 1
1988pp_data->cap[42]->ReportCount = 1
1989pp_data->cap[42]->BytePosition = 0x0004
1990pp_data->cap[42]->BitCount = 1
1991pp_data->cap[42]->BitField = 0x02
1992pp_data->cap[42]->NextBytePosition = 0x0005
1993pp_data->cap[42]->LinkCollection = 0x0001
1994pp_data->cap[42]->LinkUsagePage = 0xFF01
1995pp_data->cap[42]->LinkUsage = 0x0001
1996pp_data->cap[42]->IsMultipleItemsForArray = 0
1997pp_data->cap[42]->IsButtonCap = 1
1998pp_data->cap[42]->IsPadding = 0
1999pp_data->cap[42]->IsAbsolute = 1
2000pp_data->cap[42]->IsRange = 0
2001pp_data->cap[42]->IsAlias = 0
2002pp_data->cap[42]->IsStringRange = 0
2003pp_data->cap[42]->IsDesignatorRange = 0
2004pp_data->cap[42]->Reserved1 = 0x000000
2005pp_data->cap[42]->pp_cap->UnknownTokens[0].Token = 0x00
2006pp_data->cap[42]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2007pp_data->cap[42]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2008pp_data->cap[42]->pp_cap->UnknownTokens[1].Token = 0x00
2009pp_data->cap[42]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2010pp_data->cap[42]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2011pp_data->cap[42]->pp_cap->UnknownTokens[2].Token = 0x00
2012pp_data->cap[42]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2013pp_data->cap[42]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2014pp_data->cap[42]->pp_cap->UnknownTokens[3].Token = 0x00
2015pp_data->cap[42]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2016pp_data->cap[42]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2017pp_data->cap[42]->NotRange.Usage = 0x0002
2018pp_data->cap[42]->NotRange.Reserved1 = 0x0002
2019pp_data->cap[42]->NotRange.StringIndex = 0
2020pp_data->cap[42]->NotRange.Reserved2 = 0
2021pp_data->cap[42]->NotRange.DesignatorIndex = 0
2022pp_data->cap[42]->NotRange.Reserved3 = 0
2023pp_data->cap[42]->NotRange.DataIndex = 42
2024pp_data->cap[42]->NotRange.Reserved4 = 42
2025pp_data->cap[42]->Button.LogicalMin = 0
2026pp_data->cap[42]->Button.LogicalMax = 0
2027pp_data->cap[42]->Units = 0
2028pp_data->cap[42]->UnitsExp = 0
2029
2030pp_data->cap[43]->UsagePage = 0xFF01
2031pp_data->cap[43]->ReportID = 0x01
2032pp_data->cap[43]->BitPosition = 0
2033pp_data->cap[43]->BitSize = 1
2034pp_data->cap[43]->ReportCount = 1
2035pp_data->cap[43]->BytePosition = 0x0004
2036pp_data->cap[43]->BitCount = 1
2037pp_data->cap[43]->BitField = 0x02
2038pp_data->cap[43]->NextBytePosition = 0x0005
2039pp_data->cap[43]->LinkCollection = 0x0001
2040pp_data->cap[43]->LinkUsagePage = 0xFF01
2041pp_data->cap[43]->LinkUsage = 0x0001
2042pp_data->cap[43]->IsMultipleItemsForArray = 0
2043pp_data->cap[43]->IsButtonCap = 1
2044pp_data->cap[43]->IsPadding = 0
2045pp_data->cap[43]->IsAbsolute = 1
2046pp_data->cap[43]->IsRange = 0
2047pp_data->cap[43]->IsAlias = 0
2048pp_data->cap[43]->IsStringRange = 0
2049pp_data->cap[43]->IsDesignatorRange = 0
2050pp_data->cap[43]->Reserved1 = 0x000000
2051pp_data->cap[43]->pp_cap->UnknownTokens[0].Token = 0x00
2052pp_data->cap[43]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2053pp_data->cap[43]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2054pp_data->cap[43]->pp_cap->UnknownTokens[1].Token = 0x00
2055pp_data->cap[43]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2056pp_data->cap[43]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2057pp_data->cap[43]->pp_cap->UnknownTokens[2].Token = 0x00
2058pp_data->cap[43]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2059pp_data->cap[43]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2060pp_data->cap[43]->pp_cap->UnknownTokens[3].Token = 0x00
2061pp_data->cap[43]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2062pp_data->cap[43]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2063pp_data->cap[43]->NotRange.Usage = 0x0002
2064pp_data->cap[43]->NotRange.Reserved1 = 0x0002
2065pp_data->cap[43]->NotRange.StringIndex = 0
2066pp_data->cap[43]->NotRange.Reserved2 = 0
2067pp_data->cap[43]->NotRange.DesignatorIndex = 0
2068pp_data->cap[43]->NotRange.Reserved3 = 0
2069pp_data->cap[43]->NotRange.DataIndex = 43
2070pp_data->cap[43]->NotRange.Reserved4 = 43
2071pp_data->cap[43]->Button.LogicalMin = 0
2072pp_data->cap[43]->Button.LogicalMax = 0
2073pp_data->cap[43]->Units = 0
2074pp_data->cap[43]->UnitsExp = 0
2075
2076pp_data->cap[44]->UsagePage = 0xFF01
2077pp_data->cap[44]->ReportID = 0x01
2078pp_data->cap[44]->BitPosition = 7
2079pp_data->cap[44]->BitSize = 1
2080pp_data->cap[44]->ReportCount = 1
2081pp_data->cap[44]->BytePosition = 0x0003
2082pp_data->cap[44]->BitCount = 1
2083pp_data->cap[44]->BitField = 0x02
2084pp_data->cap[44]->NextBytePosition = 0x0004
2085pp_data->cap[44]->LinkCollection = 0x0001
2086pp_data->cap[44]->LinkUsagePage = 0xFF01
2087pp_data->cap[44]->LinkUsage = 0x0001
2088pp_data->cap[44]->IsMultipleItemsForArray = 0
2089pp_data->cap[44]->IsButtonCap = 1
2090pp_data->cap[44]->IsPadding = 0
2091pp_data->cap[44]->IsAbsolute = 1
2092pp_data->cap[44]->IsRange = 0
2093pp_data->cap[44]->IsAlias = 0
2094pp_data->cap[44]->IsStringRange = 0
2095pp_data->cap[44]->IsDesignatorRange = 0
2096pp_data->cap[44]->Reserved1 = 0x000000
2097pp_data->cap[44]->pp_cap->UnknownTokens[0].Token = 0x00
2098pp_data->cap[44]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2099pp_data->cap[44]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2100pp_data->cap[44]->pp_cap->UnknownTokens[1].Token = 0x00
2101pp_data->cap[44]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2102pp_data->cap[44]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2103pp_data->cap[44]->pp_cap->UnknownTokens[2].Token = 0x00
2104pp_data->cap[44]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2105pp_data->cap[44]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2106pp_data->cap[44]->pp_cap->UnknownTokens[3].Token = 0x00
2107pp_data->cap[44]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2108pp_data->cap[44]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2109pp_data->cap[44]->NotRange.Usage = 0x0002
2110pp_data->cap[44]->NotRange.Reserved1 = 0x0002
2111pp_data->cap[44]->NotRange.StringIndex = 0
2112pp_data->cap[44]->NotRange.Reserved2 = 0
2113pp_data->cap[44]->NotRange.DesignatorIndex = 0
2114pp_data->cap[44]->NotRange.Reserved3 = 0
2115pp_data->cap[44]->NotRange.DataIndex = 44
2116pp_data->cap[44]->NotRange.Reserved4 = 44
2117pp_data->cap[44]->Button.LogicalMin = 0
2118pp_data->cap[44]->Button.LogicalMax = 0
2119pp_data->cap[44]->Units = 0
2120pp_data->cap[44]->UnitsExp = 0
2121
2122pp_data->cap[45]->UsagePage = 0xFF01
2123pp_data->cap[45]->ReportID = 0x01
2124pp_data->cap[45]->BitPosition = 6
2125pp_data->cap[45]->BitSize = 1
2126pp_data->cap[45]->ReportCount = 1
2127pp_data->cap[45]->BytePosition = 0x0003
2128pp_data->cap[45]->BitCount = 1
2129pp_data->cap[45]->BitField = 0x02
2130pp_data->cap[45]->NextBytePosition = 0x0004
2131pp_data->cap[45]->LinkCollection = 0x0001
2132pp_data->cap[45]->LinkUsagePage = 0xFF01
2133pp_data->cap[45]->LinkUsage = 0x0001
2134pp_data->cap[45]->IsMultipleItemsForArray = 0
2135pp_data->cap[45]->IsButtonCap = 1
2136pp_data->cap[45]->IsPadding = 0
2137pp_data->cap[45]->IsAbsolute = 1
2138pp_data->cap[45]->IsRange = 0
2139pp_data->cap[45]->IsAlias = 0
2140pp_data->cap[45]->IsStringRange = 0
2141pp_data->cap[45]->IsDesignatorRange = 0
2142pp_data->cap[45]->Reserved1 = 0x000000
2143pp_data->cap[45]->pp_cap->UnknownTokens[0].Token = 0x00
2144pp_data->cap[45]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2145pp_data->cap[45]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2146pp_data->cap[45]->pp_cap->UnknownTokens[1].Token = 0x00
2147pp_data->cap[45]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2148pp_data->cap[45]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2149pp_data->cap[45]->pp_cap->UnknownTokens[2].Token = 0x00
2150pp_data->cap[45]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2151pp_data->cap[45]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2152pp_data->cap[45]->pp_cap->UnknownTokens[3].Token = 0x00
2153pp_data->cap[45]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2154pp_data->cap[45]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2155pp_data->cap[45]->NotRange.Usage = 0x0002
2156pp_data->cap[45]->NotRange.Reserved1 = 0x0002
2157pp_data->cap[45]->NotRange.StringIndex = 0
2158pp_data->cap[45]->NotRange.Reserved2 = 0
2159pp_data->cap[45]->NotRange.DesignatorIndex = 0
2160pp_data->cap[45]->NotRange.Reserved3 = 0
2161pp_data->cap[45]->NotRange.DataIndex = 45
2162pp_data->cap[45]->NotRange.Reserved4 = 45
2163pp_data->cap[45]->Button.LogicalMin = 0
2164pp_data->cap[45]->Button.LogicalMax = 0
2165pp_data->cap[45]->Units = 0
2166pp_data->cap[45]->UnitsExp = 0
2167
2168pp_data->cap[46]->UsagePage = 0xFF01
2169pp_data->cap[46]->ReportID = 0x01
2170pp_data->cap[46]->BitPosition = 5
2171pp_data->cap[46]->BitSize = 1
2172pp_data->cap[46]->ReportCount = 1
2173pp_data->cap[46]->BytePosition = 0x0003
2174pp_data->cap[46]->BitCount = 1
2175pp_data->cap[46]->BitField = 0x02
2176pp_data->cap[46]->NextBytePosition = 0x0004
2177pp_data->cap[46]->LinkCollection = 0x0001
2178pp_data->cap[46]->LinkUsagePage = 0xFF01
2179pp_data->cap[46]->LinkUsage = 0x0001
2180pp_data->cap[46]->IsMultipleItemsForArray = 0
2181pp_data->cap[46]->IsButtonCap = 1
2182pp_data->cap[46]->IsPadding = 0
2183pp_data->cap[46]->IsAbsolute = 1
2184pp_data->cap[46]->IsRange = 0
2185pp_data->cap[46]->IsAlias = 0
2186pp_data->cap[46]->IsStringRange = 0
2187pp_data->cap[46]->IsDesignatorRange = 0
2188pp_data->cap[46]->Reserved1 = 0x000000
2189pp_data->cap[46]->pp_cap->UnknownTokens[0].Token = 0x00
2190pp_data->cap[46]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2191pp_data->cap[46]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2192pp_data->cap[46]->pp_cap->UnknownTokens[1].Token = 0x00
2193pp_data->cap[46]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2194pp_data->cap[46]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2195pp_data->cap[46]->pp_cap->UnknownTokens[2].Token = 0x00
2196pp_data->cap[46]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2197pp_data->cap[46]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2198pp_data->cap[46]->pp_cap->UnknownTokens[3].Token = 0x00
2199pp_data->cap[46]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2200pp_data->cap[46]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2201pp_data->cap[46]->NotRange.Usage = 0x0002
2202pp_data->cap[46]->NotRange.Reserved1 = 0x0002
2203pp_data->cap[46]->NotRange.StringIndex = 0
2204pp_data->cap[46]->NotRange.Reserved2 = 0
2205pp_data->cap[46]->NotRange.DesignatorIndex = 0
2206pp_data->cap[46]->NotRange.Reserved3 = 0
2207pp_data->cap[46]->NotRange.DataIndex = 46
2208pp_data->cap[46]->NotRange.Reserved4 = 46
2209pp_data->cap[46]->Button.LogicalMin = 0
2210pp_data->cap[46]->Button.LogicalMax = 0
2211pp_data->cap[46]->Units = 0
2212pp_data->cap[46]->UnitsExp = 0
2213
2214pp_data->cap[47]->UsagePage = 0xFF01
2215pp_data->cap[47]->ReportID = 0x01
2216pp_data->cap[47]->BitPosition = 4
2217pp_data->cap[47]->BitSize = 1
2218pp_data->cap[47]->ReportCount = 1
2219pp_data->cap[47]->BytePosition = 0x0003
2220pp_data->cap[47]->BitCount = 1
2221pp_data->cap[47]->BitField = 0x02
2222pp_data->cap[47]->NextBytePosition = 0x0004
2223pp_data->cap[47]->LinkCollection = 0x0001
2224pp_data->cap[47]->LinkUsagePage = 0xFF01
2225pp_data->cap[47]->LinkUsage = 0x0001
2226pp_data->cap[47]->IsMultipleItemsForArray = 0
2227pp_data->cap[47]->IsButtonCap = 1
2228pp_data->cap[47]->IsPadding = 0
2229pp_data->cap[47]->IsAbsolute = 1
2230pp_data->cap[47]->IsRange = 0
2231pp_data->cap[47]->IsAlias = 0
2232pp_data->cap[47]->IsStringRange = 0
2233pp_data->cap[47]->IsDesignatorRange = 0
2234pp_data->cap[47]->Reserved1 = 0x000000
2235pp_data->cap[47]->pp_cap->UnknownTokens[0].Token = 0x00
2236pp_data->cap[47]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2237pp_data->cap[47]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2238pp_data->cap[47]->pp_cap->UnknownTokens[1].Token = 0x00
2239pp_data->cap[47]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2240pp_data->cap[47]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2241pp_data->cap[47]->pp_cap->UnknownTokens[2].Token = 0x00
2242pp_data->cap[47]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2243pp_data->cap[47]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2244pp_data->cap[47]->pp_cap->UnknownTokens[3].Token = 0x00
2245pp_data->cap[47]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2246pp_data->cap[47]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2247pp_data->cap[47]->NotRange.Usage = 0x0002
2248pp_data->cap[47]->NotRange.Reserved1 = 0x0002
2249pp_data->cap[47]->NotRange.StringIndex = 0
2250pp_data->cap[47]->NotRange.Reserved2 = 0
2251pp_data->cap[47]->NotRange.DesignatorIndex = 0
2252pp_data->cap[47]->NotRange.Reserved3 = 0
2253pp_data->cap[47]->NotRange.DataIndex = 47
2254pp_data->cap[47]->NotRange.Reserved4 = 47
2255pp_data->cap[47]->Button.LogicalMin = 0
2256pp_data->cap[47]->Button.LogicalMax = 0
2257pp_data->cap[47]->Units = 0
2258pp_data->cap[47]->UnitsExp = 0
2259
2260pp_data->cap[48]->UsagePage = 0xFF01
2261pp_data->cap[48]->ReportID = 0x01
2262pp_data->cap[48]->BitPosition = 3
2263pp_data->cap[48]->BitSize = 1
2264pp_data->cap[48]->ReportCount = 1
2265pp_data->cap[48]->BytePosition = 0x0003
2266pp_data->cap[48]->BitCount = 1
2267pp_data->cap[48]->BitField = 0x02
2268pp_data->cap[48]->NextBytePosition = 0x0004
2269pp_data->cap[48]->LinkCollection = 0x0001
2270pp_data->cap[48]->LinkUsagePage = 0xFF01
2271pp_data->cap[48]->LinkUsage = 0x0001
2272pp_data->cap[48]->IsMultipleItemsForArray = 0
2273pp_data->cap[48]->IsButtonCap = 1
2274pp_data->cap[48]->IsPadding = 0
2275pp_data->cap[48]->IsAbsolute = 1
2276pp_data->cap[48]->IsRange = 0
2277pp_data->cap[48]->IsAlias = 0
2278pp_data->cap[48]->IsStringRange = 0
2279pp_data->cap[48]->IsDesignatorRange = 0
2280pp_data->cap[48]->Reserved1 = 0x000000
2281pp_data->cap[48]->pp_cap->UnknownTokens[0].Token = 0x00
2282pp_data->cap[48]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2283pp_data->cap[48]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2284pp_data->cap[48]->pp_cap->UnknownTokens[1].Token = 0x00
2285pp_data->cap[48]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2286pp_data->cap[48]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2287pp_data->cap[48]->pp_cap->UnknownTokens[2].Token = 0x00
2288pp_data->cap[48]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2289pp_data->cap[48]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2290pp_data->cap[48]->pp_cap->UnknownTokens[3].Token = 0x00
2291pp_data->cap[48]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2292pp_data->cap[48]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2293pp_data->cap[48]->NotRange.Usage = 0x0002
2294pp_data->cap[48]->NotRange.Reserved1 = 0x0002
2295pp_data->cap[48]->NotRange.StringIndex = 0
2296pp_data->cap[48]->NotRange.Reserved2 = 0
2297pp_data->cap[48]->NotRange.DesignatorIndex = 0
2298pp_data->cap[48]->NotRange.Reserved3 = 0
2299pp_data->cap[48]->NotRange.DataIndex = 48
2300pp_data->cap[48]->NotRange.Reserved4 = 48
2301pp_data->cap[48]->Button.LogicalMin = 0
2302pp_data->cap[48]->Button.LogicalMax = 0
2303pp_data->cap[48]->Units = 0
2304pp_data->cap[48]->UnitsExp = 0
2305
2306pp_data->cap[49]->UsagePage = 0xFF01
2307pp_data->cap[49]->ReportID = 0x01
2308pp_data->cap[49]->BitPosition = 2
2309pp_data->cap[49]->BitSize = 1
2310pp_data->cap[49]->ReportCount = 1
2311pp_data->cap[49]->BytePosition = 0x0003
2312pp_data->cap[49]->BitCount = 1
2313pp_data->cap[49]->BitField = 0x02
2314pp_data->cap[49]->NextBytePosition = 0x0004
2315pp_data->cap[49]->LinkCollection = 0x0001
2316pp_data->cap[49]->LinkUsagePage = 0xFF01
2317pp_data->cap[49]->LinkUsage = 0x0001
2318pp_data->cap[49]->IsMultipleItemsForArray = 0
2319pp_data->cap[49]->IsButtonCap = 1
2320pp_data->cap[49]->IsPadding = 0
2321pp_data->cap[49]->IsAbsolute = 1
2322pp_data->cap[49]->IsRange = 0
2323pp_data->cap[49]->IsAlias = 0
2324pp_data->cap[49]->IsStringRange = 0
2325pp_data->cap[49]->IsDesignatorRange = 0
2326pp_data->cap[49]->Reserved1 = 0x000000
2327pp_data->cap[49]->pp_cap->UnknownTokens[0].Token = 0x00
2328pp_data->cap[49]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2329pp_data->cap[49]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2330pp_data->cap[49]->pp_cap->UnknownTokens[1].Token = 0x00
2331pp_data->cap[49]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2332pp_data->cap[49]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2333pp_data->cap[49]->pp_cap->UnknownTokens[2].Token = 0x00
2334pp_data->cap[49]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2335pp_data->cap[49]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2336pp_data->cap[49]->pp_cap->UnknownTokens[3].Token = 0x00
2337pp_data->cap[49]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2338pp_data->cap[49]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2339pp_data->cap[49]->NotRange.Usage = 0x0002
2340pp_data->cap[49]->NotRange.Reserved1 = 0x0002
2341pp_data->cap[49]->NotRange.StringIndex = 0
2342pp_data->cap[49]->NotRange.Reserved2 = 0
2343pp_data->cap[49]->NotRange.DesignatorIndex = 0
2344pp_data->cap[49]->NotRange.Reserved3 = 0
2345pp_data->cap[49]->NotRange.DataIndex = 49
2346pp_data->cap[49]->NotRange.Reserved4 = 49
2347pp_data->cap[49]->Button.LogicalMin = 0
2348pp_data->cap[49]->Button.LogicalMax = 0
2349pp_data->cap[49]->Units = 0
2350pp_data->cap[49]->UnitsExp = 0
2351
2352pp_data->cap[50]->UsagePage = 0xFF01
2353pp_data->cap[50]->ReportID = 0x01
2354pp_data->cap[50]->BitPosition = 1
2355pp_data->cap[50]->BitSize = 1
2356pp_data->cap[50]->ReportCount = 1
2357pp_data->cap[50]->BytePosition = 0x0003
2358pp_data->cap[50]->BitCount = 1
2359pp_data->cap[50]->BitField = 0x02
2360pp_data->cap[50]->NextBytePosition = 0x0004
2361pp_data->cap[50]->LinkCollection = 0x0001
2362pp_data->cap[50]->LinkUsagePage = 0xFF01
2363pp_data->cap[50]->LinkUsage = 0x0001
2364pp_data->cap[50]->IsMultipleItemsForArray = 0
2365pp_data->cap[50]->IsButtonCap = 1
2366pp_data->cap[50]->IsPadding = 0
2367pp_data->cap[50]->IsAbsolute = 1
2368pp_data->cap[50]->IsRange = 0
2369pp_data->cap[50]->IsAlias = 0
2370pp_data->cap[50]->IsStringRange = 0
2371pp_data->cap[50]->IsDesignatorRange = 0
2372pp_data->cap[50]->Reserved1 = 0x000000
2373pp_data->cap[50]->pp_cap->UnknownTokens[0].Token = 0x00
2374pp_data->cap[50]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2375pp_data->cap[50]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2376pp_data->cap[50]->pp_cap->UnknownTokens[1].Token = 0x00
2377pp_data->cap[50]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2378pp_data->cap[50]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2379pp_data->cap[50]->pp_cap->UnknownTokens[2].Token = 0x00
2380pp_data->cap[50]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2381pp_data->cap[50]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2382pp_data->cap[50]->pp_cap->UnknownTokens[3].Token = 0x00
2383pp_data->cap[50]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2384pp_data->cap[50]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2385pp_data->cap[50]->NotRange.Usage = 0x0002
2386pp_data->cap[50]->NotRange.Reserved1 = 0x0002
2387pp_data->cap[50]->NotRange.StringIndex = 0
2388pp_data->cap[50]->NotRange.Reserved2 = 0
2389pp_data->cap[50]->NotRange.DesignatorIndex = 0
2390pp_data->cap[50]->NotRange.Reserved3 = 0
2391pp_data->cap[50]->NotRange.DataIndex = 50
2392pp_data->cap[50]->NotRange.Reserved4 = 50
2393pp_data->cap[50]->Button.LogicalMin = 0
2394pp_data->cap[50]->Button.LogicalMax = 0
2395pp_data->cap[50]->Units = 0
2396pp_data->cap[50]->UnitsExp = 0
2397
2398pp_data->cap[51]->UsagePage = 0xFF01
2399pp_data->cap[51]->ReportID = 0x01
2400pp_data->cap[51]->BitPosition = 0
2401pp_data->cap[51]->BitSize = 1
2402pp_data->cap[51]->ReportCount = 1
2403pp_data->cap[51]->BytePosition = 0x0003
2404pp_data->cap[51]->BitCount = 1
2405pp_data->cap[51]->BitField = 0x02
2406pp_data->cap[51]->NextBytePosition = 0x0004
2407pp_data->cap[51]->LinkCollection = 0x0001
2408pp_data->cap[51]->LinkUsagePage = 0xFF01
2409pp_data->cap[51]->LinkUsage = 0x0001
2410pp_data->cap[51]->IsMultipleItemsForArray = 0
2411pp_data->cap[51]->IsButtonCap = 1
2412pp_data->cap[51]->IsPadding = 0
2413pp_data->cap[51]->IsAbsolute = 1
2414pp_data->cap[51]->IsRange = 0
2415pp_data->cap[51]->IsAlias = 0
2416pp_data->cap[51]->IsStringRange = 0
2417pp_data->cap[51]->IsDesignatorRange = 0
2418pp_data->cap[51]->Reserved1 = 0x000000
2419pp_data->cap[51]->pp_cap->UnknownTokens[0].Token = 0x00
2420pp_data->cap[51]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2421pp_data->cap[51]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2422pp_data->cap[51]->pp_cap->UnknownTokens[1].Token = 0x00
2423pp_data->cap[51]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2424pp_data->cap[51]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2425pp_data->cap[51]->pp_cap->UnknownTokens[2].Token = 0x00
2426pp_data->cap[51]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2427pp_data->cap[51]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2428pp_data->cap[51]->pp_cap->UnknownTokens[3].Token = 0x00
2429pp_data->cap[51]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2430pp_data->cap[51]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2431pp_data->cap[51]->NotRange.Usage = 0x0002
2432pp_data->cap[51]->NotRange.Reserved1 = 0x0002
2433pp_data->cap[51]->NotRange.StringIndex = 0
2434pp_data->cap[51]->NotRange.Reserved2 = 0
2435pp_data->cap[51]->NotRange.DesignatorIndex = 0
2436pp_data->cap[51]->NotRange.Reserved3 = 0
2437pp_data->cap[51]->NotRange.DataIndex = 51
2438pp_data->cap[51]->NotRange.Reserved4 = 51
2439pp_data->cap[51]->Button.LogicalMin = 0
2440pp_data->cap[51]->Button.LogicalMax = 0
2441pp_data->cap[51]->Units = 0
2442pp_data->cap[51]->UnitsExp = 0
2443
2444pp_data->cap[52]->UsagePage = 0xFF01
2445pp_data->cap[52]->ReportID = 0x01
2446pp_data->cap[52]->BitPosition = 7
2447pp_data->cap[52]->BitSize = 1
2448pp_data->cap[52]->ReportCount = 1
2449pp_data->cap[52]->BytePosition = 0x0009
2450pp_data->cap[52]->BitCount = 1
2451pp_data->cap[52]->BitField = 0x02
2452pp_data->cap[52]->NextBytePosition = 0x000A
2453pp_data->cap[52]->LinkCollection = 0x0001
2454pp_data->cap[52]->LinkUsagePage = 0xFF01
2455pp_data->cap[52]->LinkUsage = 0x0001
2456pp_data->cap[52]->IsMultipleItemsForArray = 0
2457pp_data->cap[52]->IsButtonCap = 1
2458pp_data->cap[52]->IsPadding = 0
2459pp_data->cap[52]->IsAbsolute = 1
2460pp_data->cap[52]->IsRange = 0
2461pp_data->cap[52]->IsAlias = 0
2462pp_data->cap[52]->IsStringRange = 0
2463pp_data->cap[52]->IsDesignatorRange = 0
2464pp_data->cap[52]->Reserved1 = 0x000000
2465pp_data->cap[52]->pp_cap->UnknownTokens[0].Token = 0x00
2466pp_data->cap[52]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2467pp_data->cap[52]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2468pp_data->cap[52]->pp_cap->UnknownTokens[1].Token = 0x00
2469pp_data->cap[52]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2470pp_data->cap[52]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2471pp_data->cap[52]->pp_cap->UnknownTokens[2].Token = 0x00
2472pp_data->cap[52]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2473pp_data->cap[52]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2474pp_data->cap[52]->pp_cap->UnknownTokens[3].Token = 0x00
2475pp_data->cap[52]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2476pp_data->cap[52]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2477pp_data->cap[52]->NotRange.Usage = 0x000B
2478pp_data->cap[52]->NotRange.Reserved1 = 0x000B
2479pp_data->cap[52]->NotRange.StringIndex = 0
2480pp_data->cap[52]->NotRange.Reserved2 = 0
2481pp_data->cap[52]->NotRange.DesignatorIndex = 0
2482pp_data->cap[52]->NotRange.Reserved3 = 0
2483pp_data->cap[52]->NotRange.DataIndex = 52
2484pp_data->cap[52]->NotRange.Reserved4 = 52
2485pp_data->cap[52]->Button.LogicalMin = 0
2486pp_data->cap[52]->Button.LogicalMax = 0
2487pp_data->cap[52]->Units = 0
2488pp_data->cap[52]->UnitsExp = 0
2489
2490pp_data->cap[53]->UsagePage = 0xFF01
2491pp_data->cap[53]->ReportID = 0x01
2492pp_data->cap[53]->BitPosition = 6
2493pp_data->cap[53]->BitSize = 1
2494pp_data->cap[53]->ReportCount = 1
2495pp_data->cap[53]->BytePosition = 0x0009
2496pp_data->cap[53]->BitCount = 1
2497pp_data->cap[53]->BitField = 0x02
2498pp_data->cap[53]->NextBytePosition = 0x000A
2499pp_data->cap[53]->LinkCollection = 0x0001
2500pp_data->cap[53]->LinkUsagePage = 0xFF01
2501pp_data->cap[53]->LinkUsage = 0x0001
2502pp_data->cap[53]->IsMultipleItemsForArray = 0
2503pp_data->cap[53]->IsButtonCap = 1
2504pp_data->cap[53]->IsPadding = 0
2505pp_data->cap[53]->IsAbsolute = 1
2506pp_data->cap[53]->IsRange = 0
2507pp_data->cap[53]->IsAlias = 0
2508pp_data->cap[53]->IsStringRange = 0
2509pp_data->cap[53]->IsDesignatorRange = 0
2510pp_data->cap[53]->Reserved1 = 0x000000
2511pp_data->cap[53]->pp_cap->UnknownTokens[0].Token = 0x00
2512pp_data->cap[53]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2513pp_data->cap[53]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2514pp_data->cap[53]->pp_cap->UnknownTokens[1].Token = 0x00
2515pp_data->cap[53]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2516pp_data->cap[53]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2517pp_data->cap[53]->pp_cap->UnknownTokens[2].Token = 0x00
2518pp_data->cap[53]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2519pp_data->cap[53]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2520pp_data->cap[53]->pp_cap->UnknownTokens[3].Token = 0x00
2521pp_data->cap[53]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2522pp_data->cap[53]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2523pp_data->cap[53]->NotRange.Usage = 0x000B
2524pp_data->cap[53]->NotRange.Reserved1 = 0x000B
2525pp_data->cap[53]->NotRange.StringIndex = 0
2526pp_data->cap[53]->NotRange.Reserved2 = 0
2527pp_data->cap[53]->NotRange.DesignatorIndex = 0
2528pp_data->cap[53]->NotRange.Reserved3 = 0
2529pp_data->cap[53]->NotRange.DataIndex = 53
2530pp_data->cap[53]->NotRange.Reserved4 = 53
2531pp_data->cap[53]->Button.LogicalMin = 0
2532pp_data->cap[53]->Button.LogicalMax = 0
2533pp_data->cap[53]->Units = 0
2534pp_data->cap[53]->UnitsExp = 0
2535
2536pp_data->cap[54]->UsagePage = 0xFF01
2537pp_data->cap[54]->ReportID = 0x01
2538pp_data->cap[54]->BitPosition = 5
2539pp_data->cap[54]->BitSize = 1
2540pp_data->cap[54]->ReportCount = 1
2541pp_data->cap[54]->BytePosition = 0x0009
2542pp_data->cap[54]->BitCount = 1
2543pp_data->cap[54]->BitField = 0x02
2544pp_data->cap[54]->NextBytePosition = 0x000A
2545pp_data->cap[54]->LinkCollection = 0x0001
2546pp_data->cap[54]->LinkUsagePage = 0xFF01
2547pp_data->cap[54]->LinkUsage = 0x0001
2548pp_data->cap[54]->IsMultipleItemsForArray = 0
2549pp_data->cap[54]->IsButtonCap = 1
2550pp_data->cap[54]->IsPadding = 0
2551pp_data->cap[54]->IsAbsolute = 1
2552pp_data->cap[54]->IsRange = 0
2553pp_data->cap[54]->IsAlias = 0
2554pp_data->cap[54]->IsStringRange = 0
2555pp_data->cap[54]->IsDesignatorRange = 0
2556pp_data->cap[54]->Reserved1 = 0x000000
2557pp_data->cap[54]->pp_cap->UnknownTokens[0].Token = 0x00
2558pp_data->cap[54]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2559pp_data->cap[54]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2560pp_data->cap[54]->pp_cap->UnknownTokens[1].Token = 0x00
2561pp_data->cap[54]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2562pp_data->cap[54]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2563pp_data->cap[54]->pp_cap->UnknownTokens[2].Token = 0x00
2564pp_data->cap[54]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2565pp_data->cap[54]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2566pp_data->cap[54]->pp_cap->UnknownTokens[3].Token = 0x00
2567pp_data->cap[54]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2568pp_data->cap[54]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2569pp_data->cap[54]->NotRange.Usage = 0x000B
2570pp_data->cap[54]->NotRange.Reserved1 = 0x000B
2571pp_data->cap[54]->NotRange.StringIndex = 0
2572pp_data->cap[54]->NotRange.Reserved2 = 0
2573pp_data->cap[54]->NotRange.DesignatorIndex = 0
2574pp_data->cap[54]->NotRange.Reserved3 = 0
2575pp_data->cap[54]->NotRange.DataIndex = 54
2576pp_data->cap[54]->NotRange.Reserved4 = 54
2577pp_data->cap[54]->Button.LogicalMin = 0
2578pp_data->cap[54]->Button.LogicalMax = 0
2579pp_data->cap[54]->Units = 0
2580pp_data->cap[54]->UnitsExp = 0
2581
2582pp_data->cap[55]->UsagePage = 0xFF01
2583pp_data->cap[55]->ReportID = 0x01
2584pp_data->cap[55]->BitPosition = 4
2585pp_data->cap[55]->BitSize = 1
2586pp_data->cap[55]->ReportCount = 1
2587pp_data->cap[55]->BytePosition = 0x0009
2588pp_data->cap[55]->BitCount = 1
2589pp_data->cap[55]->BitField = 0x02
2590pp_data->cap[55]->NextBytePosition = 0x000A
2591pp_data->cap[55]->LinkCollection = 0x0001
2592pp_data->cap[55]->LinkUsagePage = 0xFF01
2593pp_data->cap[55]->LinkUsage = 0x0001
2594pp_data->cap[55]->IsMultipleItemsForArray = 0
2595pp_data->cap[55]->IsButtonCap = 1
2596pp_data->cap[55]->IsPadding = 0
2597pp_data->cap[55]->IsAbsolute = 1
2598pp_data->cap[55]->IsRange = 0
2599pp_data->cap[55]->IsAlias = 0
2600pp_data->cap[55]->IsStringRange = 0
2601pp_data->cap[55]->IsDesignatorRange = 0
2602pp_data->cap[55]->Reserved1 = 0x000000
2603pp_data->cap[55]->pp_cap->UnknownTokens[0].Token = 0x00
2604pp_data->cap[55]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2605pp_data->cap[55]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2606pp_data->cap[55]->pp_cap->UnknownTokens[1].Token = 0x00
2607pp_data->cap[55]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2608pp_data->cap[55]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2609pp_data->cap[55]->pp_cap->UnknownTokens[2].Token = 0x00
2610pp_data->cap[55]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2611pp_data->cap[55]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2612pp_data->cap[55]->pp_cap->UnknownTokens[3].Token = 0x00
2613pp_data->cap[55]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2614pp_data->cap[55]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2615pp_data->cap[55]->NotRange.Usage = 0x000B
2616pp_data->cap[55]->NotRange.Reserved1 = 0x000B
2617pp_data->cap[55]->NotRange.StringIndex = 0
2618pp_data->cap[55]->NotRange.Reserved2 = 0
2619pp_data->cap[55]->NotRange.DesignatorIndex = 0
2620pp_data->cap[55]->NotRange.Reserved3 = 0
2621pp_data->cap[55]->NotRange.DataIndex = 55
2622pp_data->cap[55]->NotRange.Reserved4 = 55
2623pp_data->cap[55]->Button.LogicalMin = 0
2624pp_data->cap[55]->Button.LogicalMax = 0
2625pp_data->cap[55]->Units = 0
2626pp_data->cap[55]->UnitsExp = 0
2627
2628pp_data->cap[56]->UsagePage = 0xFF01
2629pp_data->cap[56]->ReportID = 0x01
2630pp_data->cap[56]->BitPosition = 3
2631pp_data->cap[56]->BitSize = 1
2632pp_data->cap[56]->ReportCount = 1
2633pp_data->cap[56]->BytePosition = 0x0009
2634pp_data->cap[56]->BitCount = 1
2635pp_data->cap[56]->BitField = 0x02
2636pp_data->cap[56]->NextBytePosition = 0x000A
2637pp_data->cap[56]->LinkCollection = 0x0001
2638pp_data->cap[56]->LinkUsagePage = 0xFF01
2639pp_data->cap[56]->LinkUsage = 0x0001
2640pp_data->cap[56]->IsMultipleItemsForArray = 0
2641pp_data->cap[56]->IsButtonCap = 1
2642pp_data->cap[56]->IsPadding = 0
2643pp_data->cap[56]->IsAbsolute = 1
2644pp_data->cap[56]->IsRange = 0
2645pp_data->cap[56]->IsAlias = 0
2646pp_data->cap[56]->IsStringRange = 0
2647pp_data->cap[56]->IsDesignatorRange = 0
2648pp_data->cap[56]->Reserved1 = 0x000000
2649pp_data->cap[56]->pp_cap->UnknownTokens[0].Token = 0x00
2650pp_data->cap[56]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2651pp_data->cap[56]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2652pp_data->cap[56]->pp_cap->UnknownTokens[1].Token = 0x00
2653pp_data->cap[56]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2654pp_data->cap[56]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2655pp_data->cap[56]->pp_cap->UnknownTokens[2].Token = 0x00
2656pp_data->cap[56]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2657pp_data->cap[56]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2658pp_data->cap[56]->pp_cap->UnknownTokens[3].Token = 0x00
2659pp_data->cap[56]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2660pp_data->cap[56]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2661pp_data->cap[56]->NotRange.Usage = 0x000B
2662pp_data->cap[56]->NotRange.Reserved1 = 0x000B
2663pp_data->cap[56]->NotRange.StringIndex = 0
2664pp_data->cap[56]->NotRange.Reserved2 = 0
2665pp_data->cap[56]->NotRange.DesignatorIndex = 0
2666pp_data->cap[56]->NotRange.Reserved3 = 0
2667pp_data->cap[56]->NotRange.DataIndex = 56
2668pp_data->cap[56]->NotRange.Reserved4 = 56
2669pp_data->cap[56]->Button.LogicalMin = 0
2670pp_data->cap[56]->Button.LogicalMax = 0
2671pp_data->cap[56]->Units = 0
2672pp_data->cap[56]->UnitsExp = 0
2673
2674pp_data->cap[57]->UsagePage = 0xFF01
2675pp_data->cap[57]->ReportID = 0x01
2676pp_data->cap[57]->BitPosition = 2
2677pp_data->cap[57]->BitSize = 1
2678pp_data->cap[57]->ReportCount = 1
2679pp_data->cap[57]->BytePosition = 0x0009
2680pp_data->cap[57]->BitCount = 1
2681pp_data->cap[57]->BitField = 0x02
2682pp_data->cap[57]->NextBytePosition = 0x000A
2683pp_data->cap[57]->LinkCollection = 0x0001
2684pp_data->cap[57]->LinkUsagePage = 0xFF01
2685pp_data->cap[57]->LinkUsage = 0x0001
2686pp_data->cap[57]->IsMultipleItemsForArray = 0
2687pp_data->cap[57]->IsButtonCap = 1
2688pp_data->cap[57]->IsPadding = 0
2689pp_data->cap[57]->IsAbsolute = 1
2690pp_data->cap[57]->IsRange = 0
2691pp_data->cap[57]->IsAlias = 0
2692pp_data->cap[57]->IsStringRange = 0
2693pp_data->cap[57]->IsDesignatorRange = 0
2694pp_data->cap[57]->Reserved1 = 0x000000
2695pp_data->cap[57]->pp_cap->UnknownTokens[0].Token = 0x00
2696pp_data->cap[57]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2697pp_data->cap[57]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2698pp_data->cap[57]->pp_cap->UnknownTokens[1].Token = 0x00
2699pp_data->cap[57]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2700pp_data->cap[57]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2701pp_data->cap[57]->pp_cap->UnknownTokens[2].Token = 0x00
2702pp_data->cap[57]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2703pp_data->cap[57]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2704pp_data->cap[57]->pp_cap->UnknownTokens[3].Token = 0x00
2705pp_data->cap[57]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2706pp_data->cap[57]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2707pp_data->cap[57]->NotRange.Usage = 0x000B
2708pp_data->cap[57]->NotRange.Reserved1 = 0x000B
2709pp_data->cap[57]->NotRange.StringIndex = 0
2710pp_data->cap[57]->NotRange.Reserved2 = 0
2711pp_data->cap[57]->NotRange.DesignatorIndex = 0
2712pp_data->cap[57]->NotRange.Reserved3 = 0
2713pp_data->cap[57]->NotRange.DataIndex = 57
2714pp_data->cap[57]->NotRange.Reserved4 = 57
2715pp_data->cap[57]->Button.LogicalMin = 0
2716pp_data->cap[57]->Button.LogicalMax = 0
2717pp_data->cap[57]->Units = 0
2718pp_data->cap[57]->UnitsExp = 0
2719
2720pp_data->cap[58]->UsagePage = 0xFF01
2721pp_data->cap[58]->ReportID = 0x01
2722pp_data->cap[58]->BitPosition = 1
2723pp_data->cap[58]->BitSize = 1
2724pp_data->cap[58]->ReportCount = 1
2725pp_data->cap[58]->BytePosition = 0x0009
2726pp_data->cap[58]->BitCount = 1
2727pp_data->cap[58]->BitField = 0x02
2728pp_data->cap[58]->NextBytePosition = 0x000A
2729pp_data->cap[58]->LinkCollection = 0x0001
2730pp_data->cap[58]->LinkUsagePage = 0xFF01
2731pp_data->cap[58]->LinkUsage = 0x0001
2732pp_data->cap[58]->IsMultipleItemsForArray = 0
2733pp_data->cap[58]->IsButtonCap = 1
2734pp_data->cap[58]->IsPadding = 0
2735pp_data->cap[58]->IsAbsolute = 1
2736pp_data->cap[58]->IsRange = 0
2737pp_data->cap[58]->IsAlias = 0
2738pp_data->cap[58]->IsStringRange = 0
2739pp_data->cap[58]->IsDesignatorRange = 0
2740pp_data->cap[58]->Reserved1 = 0x000000
2741pp_data->cap[58]->pp_cap->UnknownTokens[0].Token = 0x00
2742pp_data->cap[58]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2743pp_data->cap[58]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2744pp_data->cap[58]->pp_cap->UnknownTokens[1].Token = 0x00
2745pp_data->cap[58]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2746pp_data->cap[58]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2747pp_data->cap[58]->pp_cap->UnknownTokens[2].Token = 0x00
2748pp_data->cap[58]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2749pp_data->cap[58]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2750pp_data->cap[58]->pp_cap->UnknownTokens[3].Token = 0x00
2751pp_data->cap[58]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2752pp_data->cap[58]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2753pp_data->cap[58]->NotRange.Usage = 0x000B
2754pp_data->cap[58]->NotRange.Reserved1 = 0x000B
2755pp_data->cap[58]->NotRange.StringIndex = 0
2756pp_data->cap[58]->NotRange.Reserved2 = 0
2757pp_data->cap[58]->NotRange.DesignatorIndex = 0
2758pp_data->cap[58]->NotRange.Reserved3 = 0
2759pp_data->cap[58]->NotRange.DataIndex = 58
2760pp_data->cap[58]->NotRange.Reserved4 = 58
2761pp_data->cap[58]->Button.LogicalMin = 0
2762pp_data->cap[58]->Button.LogicalMax = 0
2763pp_data->cap[58]->Units = 0
2764pp_data->cap[58]->UnitsExp = 0
2765
2766pp_data->cap[59]->UsagePage = 0xFF01
2767pp_data->cap[59]->ReportID = 0x01
2768pp_data->cap[59]->BitPosition = 0
2769pp_data->cap[59]->BitSize = 1
2770pp_data->cap[59]->ReportCount = 1
2771pp_data->cap[59]->BytePosition = 0x0009
2772pp_data->cap[59]->BitCount = 1
2773pp_data->cap[59]->BitField = 0x02
2774pp_data->cap[59]->NextBytePosition = 0x000A
2775pp_data->cap[59]->LinkCollection = 0x0001
2776pp_data->cap[59]->LinkUsagePage = 0xFF01
2777pp_data->cap[59]->LinkUsage = 0x0001
2778pp_data->cap[59]->IsMultipleItemsForArray = 0
2779pp_data->cap[59]->IsButtonCap = 1
2780pp_data->cap[59]->IsPadding = 0
2781pp_data->cap[59]->IsAbsolute = 1
2782pp_data->cap[59]->IsRange = 0
2783pp_data->cap[59]->IsAlias = 0
2784pp_data->cap[59]->IsStringRange = 0
2785pp_data->cap[59]->IsDesignatorRange = 0
2786pp_data->cap[59]->Reserved1 = 0x000000
2787pp_data->cap[59]->pp_cap->UnknownTokens[0].Token = 0x00
2788pp_data->cap[59]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2789pp_data->cap[59]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2790pp_data->cap[59]->pp_cap->UnknownTokens[1].Token = 0x00
2791pp_data->cap[59]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2792pp_data->cap[59]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2793pp_data->cap[59]->pp_cap->UnknownTokens[2].Token = 0x00
2794pp_data->cap[59]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2795pp_data->cap[59]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2796pp_data->cap[59]->pp_cap->UnknownTokens[3].Token = 0x00
2797pp_data->cap[59]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2798pp_data->cap[59]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2799pp_data->cap[59]->NotRange.Usage = 0x000B
2800pp_data->cap[59]->NotRange.Reserved1 = 0x000B
2801pp_data->cap[59]->NotRange.StringIndex = 0
2802pp_data->cap[59]->NotRange.Reserved2 = 0
2803pp_data->cap[59]->NotRange.DesignatorIndex = 0
2804pp_data->cap[59]->NotRange.Reserved3 = 0
2805pp_data->cap[59]->NotRange.DataIndex = 59
2806pp_data->cap[59]->NotRange.Reserved4 = 59
2807pp_data->cap[59]->Button.LogicalMin = 0
2808pp_data->cap[59]->Button.LogicalMax = 0
2809pp_data->cap[59]->Units = 0
2810pp_data->cap[59]->UnitsExp = 0
2811
2812pp_data->cap[60]->UsagePage = 0xFF01
2813pp_data->cap[60]->ReportID = 0x02
2814pp_data->cap[60]->BitPosition = 0
2815pp_data->cap[60]->BitSize = 16
2816pp_data->cap[60]->ReportCount = 1
2817pp_data->cap[60]->BytePosition = 0x0033
2818pp_data->cap[60]->BitCount = 16
2819pp_data->cap[60]->BitField = 0x02
2820pp_data->cap[60]->NextBytePosition = 0x0035
2821pp_data->cap[60]->LinkCollection = 0x0002
2822pp_data->cap[60]->LinkUsagePage = 0xFF01
2823pp_data->cap[60]->LinkUsage = 0x0002
2824pp_data->cap[60]->IsMultipleItemsForArray = 0
2825pp_data->cap[60]->IsButtonCap = 0
2826pp_data->cap[60]->IsPadding = 0
2827pp_data->cap[60]->IsAbsolute = 1
2828pp_data->cap[60]->IsRange = 0
2829pp_data->cap[60]->IsAlias = 0
2830pp_data->cap[60]->IsStringRange = 0
2831pp_data->cap[60]->IsDesignatorRange = 0
2832pp_data->cap[60]->Reserved1 = 0x000000
2833pp_data->cap[60]->pp_cap->UnknownTokens[0].Token = 0x00
2834pp_data->cap[60]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2835pp_data->cap[60]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2836pp_data->cap[60]->pp_cap->UnknownTokens[1].Token = 0x00
2837pp_data->cap[60]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2838pp_data->cap[60]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2839pp_data->cap[60]->pp_cap->UnknownTokens[2].Token = 0x00
2840pp_data->cap[60]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2841pp_data->cap[60]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2842pp_data->cap[60]->pp_cap->UnknownTokens[3].Token = 0x00
2843pp_data->cap[60]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2844pp_data->cap[60]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2845pp_data->cap[60]->NotRange.Usage = 0x0004
2846pp_data->cap[60]->NotRange.Reserved1 = 0x0004
2847pp_data->cap[60]->NotRange.StringIndex = 0
2848pp_data->cap[60]->NotRange.Reserved2 = 0
2849pp_data->cap[60]->NotRange.DesignatorIndex = 0
2850pp_data->cap[60]->NotRange.Reserved3 = 0
2851pp_data->cap[60]->NotRange.DataIndex = 60
2852pp_data->cap[60]->NotRange.Reserved4 = 60
2853pp_data->cap[60]->NotButton.HasNull = 0
2854pp_data->cap[60]->NotButton.Reserved4 = 0x000000
2855pp_data->cap[60]->NotButton.LogicalMin = 0
2856pp_data->cap[60]->NotButton.LogicalMax = 4095
2857pp_data->cap[60]->NotButton.PhysicalMin = 0
2858pp_data->cap[60]->NotButton.PhysicalMax = 0
2859pp_data->cap[60]->Units = 0
2860pp_data->cap[60]->UnitsExp = 0
2861
2862pp_data->cap[61]->UsagePage = 0xFF01
2863pp_data->cap[61]->ReportID = 0x02
2864pp_data->cap[61]->BitPosition = 0
2865pp_data->cap[61]->BitSize = 16
2866pp_data->cap[61]->ReportCount = 1
2867pp_data->cap[61]->BytePosition = 0x0031
2868pp_data->cap[61]->BitCount = 16
2869pp_data->cap[61]->BitField = 0x02
2870pp_data->cap[61]->NextBytePosition = 0x0033
2871pp_data->cap[61]->LinkCollection = 0x0002
2872pp_data->cap[61]->LinkUsagePage = 0xFF01
2873pp_data->cap[61]->LinkUsage = 0x0002
2874pp_data->cap[61]->IsMultipleItemsForArray = 0
2875pp_data->cap[61]->IsButtonCap = 0
2876pp_data->cap[61]->IsPadding = 0
2877pp_data->cap[61]->IsAbsolute = 1
2878pp_data->cap[61]->IsRange = 0
2879pp_data->cap[61]->IsAlias = 0
2880pp_data->cap[61]->IsStringRange = 0
2881pp_data->cap[61]->IsDesignatorRange = 0
2882pp_data->cap[61]->Reserved1 = 0x000000
2883pp_data->cap[61]->pp_cap->UnknownTokens[0].Token = 0x00
2884pp_data->cap[61]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2885pp_data->cap[61]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2886pp_data->cap[61]->pp_cap->UnknownTokens[1].Token = 0x00
2887pp_data->cap[61]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2888pp_data->cap[61]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2889pp_data->cap[61]->pp_cap->UnknownTokens[2].Token = 0x00
2890pp_data->cap[61]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2891pp_data->cap[61]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2892pp_data->cap[61]->pp_cap->UnknownTokens[3].Token = 0x00
2893pp_data->cap[61]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2894pp_data->cap[61]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2895pp_data->cap[61]->NotRange.Usage = 0x0004
2896pp_data->cap[61]->NotRange.Reserved1 = 0x0004
2897pp_data->cap[61]->NotRange.StringIndex = 0
2898pp_data->cap[61]->NotRange.Reserved2 = 0
2899pp_data->cap[61]->NotRange.DesignatorIndex = 0
2900pp_data->cap[61]->NotRange.Reserved3 = 0
2901pp_data->cap[61]->NotRange.DataIndex = 61
2902pp_data->cap[61]->NotRange.Reserved4 = 61
2903pp_data->cap[61]->NotButton.HasNull = 0
2904pp_data->cap[61]->NotButton.Reserved4 = 0x000000
2905pp_data->cap[61]->NotButton.LogicalMin = 0
2906pp_data->cap[61]->NotButton.LogicalMax = 4095
2907pp_data->cap[61]->NotButton.PhysicalMin = 0
2908pp_data->cap[61]->NotButton.PhysicalMax = 0
2909pp_data->cap[61]->Units = 0
2910pp_data->cap[61]->UnitsExp = 0
2911
2912pp_data->cap[62]->UsagePage = 0xFF01
2913pp_data->cap[62]->ReportID = 0x02
2914pp_data->cap[62]->BitPosition = 0
2915pp_data->cap[62]->BitSize = 16
2916pp_data->cap[62]->ReportCount = 1
2917pp_data->cap[62]->BytePosition = 0x002F
2918pp_data->cap[62]->BitCount = 16
2919pp_data->cap[62]->BitField = 0x02
2920pp_data->cap[62]->NextBytePosition = 0x0031
2921pp_data->cap[62]->LinkCollection = 0x0002
2922pp_data->cap[62]->LinkUsagePage = 0xFF01
2923pp_data->cap[62]->LinkUsage = 0x0002
2924pp_data->cap[62]->IsMultipleItemsForArray = 0
2925pp_data->cap[62]->IsButtonCap = 0
2926pp_data->cap[62]->IsPadding = 0
2927pp_data->cap[62]->IsAbsolute = 1
2928pp_data->cap[62]->IsRange = 0
2929pp_data->cap[62]->IsAlias = 0
2930pp_data->cap[62]->IsStringRange = 0
2931pp_data->cap[62]->IsDesignatorRange = 0
2932pp_data->cap[62]->Reserved1 = 0x000000
2933pp_data->cap[62]->pp_cap->UnknownTokens[0].Token = 0x00
2934pp_data->cap[62]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2935pp_data->cap[62]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2936pp_data->cap[62]->pp_cap->UnknownTokens[1].Token = 0x00
2937pp_data->cap[62]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2938pp_data->cap[62]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2939pp_data->cap[62]->pp_cap->UnknownTokens[2].Token = 0x00
2940pp_data->cap[62]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2941pp_data->cap[62]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2942pp_data->cap[62]->pp_cap->UnknownTokens[3].Token = 0x00
2943pp_data->cap[62]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2944pp_data->cap[62]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2945pp_data->cap[62]->NotRange.Usage = 0x0004
2946pp_data->cap[62]->NotRange.Reserved1 = 0x0004
2947pp_data->cap[62]->NotRange.StringIndex = 0
2948pp_data->cap[62]->NotRange.Reserved2 = 0
2949pp_data->cap[62]->NotRange.DesignatorIndex = 0
2950pp_data->cap[62]->NotRange.Reserved3 = 0
2951pp_data->cap[62]->NotRange.DataIndex = 62
2952pp_data->cap[62]->NotRange.Reserved4 = 62
2953pp_data->cap[62]->NotButton.HasNull = 0
2954pp_data->cap[62]->NotButton.Reserved4 = 0x000000
2955pp_data->cap[62]->NotButton.LogicalMin = 0
2956pp_data->cap[62]->NotButton.LogicalMax = 4095
2957pp_data->cap[62]->NotButton.PhysicalMin = 0
2958pp_data->cap[62]->NotButton.PhysicalMax = 0
2959pp_data->cap[62]->Units = 0
2960pp_data->cap[62]->UnitsExp = 0
2961
2962pp_data->cap[63]->UsagePage = 0xFF01
2963pp_data->cap[63]->ReportID = 0x02
2964pp_data->cap[63]->BitPosition = 0
2965pp_data->cap[63]->BitSize = 16
2966pp_data->cap[63]->ReportCount = 1
2967pp_data->cap[63]->BytePosition = 0x002D
2968pp_data->cap[63]->BitCount = 16
2969pp_data->cap[63]->BitField = 0x02
2970pp_data->cap[63]->NextBytePosition = 0x002F
2971pp_data->cap[63]->LinkCollection = 0x0002
2972pp_data->cap[63]->LinkUsagePage = 0xFF01
2973pp_data->cap[63]->LinkUsage = 0x0002
2974pp_data->cap[63]->IsMultipleItemsForArray = 0
2975pp_data->cap[63]->IsButtonCap = 0
2976pp_data->cap[63]->IsPadding = 0
2977pp_data->cap[63]->IsAbsolute = 1
2978pp_data->cap[63]->IsRange = 0
2979pp_data->cap[63]->IsAlias = 0
2980pp_data->cap[63]->IsStringRange = 0
2981pp_data->cap[63]->IsDesignatorRange = 0
2982pp_data->cap[63]->Reserved1 = 0x000000
2983pp_data->cap[63]->pp_cap->UnknownTokens[0].Token = 0x00
2984pp_data->cap[63]->pp_cap->UnknownTokens[0].Reserved = 0x000000
2985pp_data->cap[63]->pp_cap->UnknownTokens[0].BitField = 0x00000000
2986pp_data->cap[63]->pp_cap->UnknownTokens[1].Token = 0x00
2987pp_data->cap[63]->pp_cap->UnknownTokens[1].Reserved = 0x000000
2988pp_data->cap[63]->pp_cap->UnknownTokens[1].BitField = 0x00000000
2989pp_data->cap[63]->pp_cap->UnknownTokens[2].Token = 0x00
2990pp_data->cap[63]->pp_cap->UnknownTokens[2].Reserved = 0x000000
2991pp_data->cap[63]->pp_cap->UnknownTokens[2].BitField = 0x00000000
2992pp_data->cap[63]->pp_cap->UnknownTokens[3].Token = 0x00
2993pp_data->cap[63]->pp_cap->UnknownTokens[3].Reserved = 0x000000
2994pp_data->cap[63]->pp_cap->UnknownTokens[3].BitField = 0x00000000
2995pp_data->cap[63]->NotRange.Usage = 0x0004
2996pp_data->cap[63]->NotRange.Reserved1 = 0x0004
2997pp_data->cap[63]->NotRange.StringIndex = 0
2998pp_data->cap[63]->NotRange.Reserved2 = 0
2999pp_data->cap[63]->NotRange.DesignatorIndex = 0
3000pp_data->cap[63]->NotRange.Reserved3 = 0
3001pp_data->cap[63]->NotRange.DataIndex = 63
3002pp_data->cap[63]->NotRange.Reserved4 = 63
3003pp_data->cap[63]->NotButton.HasNull = 0
3004pp_data->cap[63]->NotButton.Reserved4 = 0x000000
3005pp_data->cap[63]->NotButton.LogicalMin = 0
3006pp_data->cap[63]->NotButton.LogicalMax = 4095
3007pp_data->cap[63]->NotButton.PhysicalMin = 0
3008pp_data->cap[63]->NotButton.PhysicalMax = 0
3009pp_data->cap[63]->Units = 0
3010pp_data->cap[63]->UnitsExp = 0
3011
3012pp_data->cap[64]->UsagePage = 0xFF01
3013pp_data->cap[64]->ReportID = 0x02
3014pp_data->cap[64]->BitPosition = 0
3015pp_data->cap[64]->BitSize = 16
3016pp_data->cap[64]->ReportCount = 1
3017pp_data->cap[64]->BytePosition = 0x002B
3018pp_data->cap[64]->BitCount = 16
3019pp_data->cap[64]->BitField = 0x02
3020pp_data->cap[64]->NextBytePosition = 0x002D
3021pp_data->cap[64]->LinkCollection = 0x0002
3022pp_data->cap[64]->LinkUsagePage = 0xFF01
3023pp_data->cap[64]->LinkUsage = 0x0002
3024pp_data->cap[64]->IsMultipleItemsForArray = 0
3025pp_data->cap[64]->IsButtonCap = 0
3026pp_data->cap[64]->IsPadding = 0
3027pp_data->cap[64]->IsAbsolute = 1
3028pp_data->cap[64]->IsRange = 0
3029pp_data->cap[64]->IsAlias = 0
3030pp_data->cap[64]->IsStringRange = 0
3031pp_data->cap[64]->IsDesignatorRange = 0
3032pp_data->cap[64]->Reserved1 = 0x000000
3033pp_data->cap[64]->pp_cap->UnknownTokens[0].Token = 0x00
3034pp_data->cap[64]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3035pp_data->cap[64]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3036pp_data->cap[64]->pp_cap->UnknownTokens[1].Token = 0x00
3037pp_data->cap[64]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3038pp_data->cap[64]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3039pp_data->cap[64]->pp_cap->UnknownTokens[2].Token = 0x00
3040pp_data->cap[64]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3041pp_data->cap[64]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3042pp_data->cap[64]->pp_cap->UnknownTokens[3].Token = 0x00
3043pp_data->cap[64]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3044pp_data->cap[64]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3045pp_data->cap[64]->NotRange.Usage = 0x0004
3046pp_data->cap[64]->NotRange.Reserved1 = 0x0004
3047pp_data->cap[64]->NotRange.StringIndex = 0
3048pp_data->cap[64]->NotRange.Reserved2 = 0
3049pp_data->cap[64]->NotRange.DesignatorIndex = 0
3050pp_data->cap[64]->NotRange.Reserved3 = 0
3051pp_data->cap[64]->NotRange.DataIndex = 64
3052pp_data->cap[64]->NotRange.Reserved4 = 64
3053pp_data->cap[64]->NotButton.HasNull = 0
3054pp_data->cap[64]->NotButton.Reserved4 = 0x000000
3055pp_data->cap[64]->NotButton.LogicalMin = 0
3056pp_data->cap[64]->NotButton.LogicalMax = 4095
3057pp_data->cap[64]->NotButton.PhysicalMin = 0
3058pp_data->cap[64]->NotButton.PhysicalMax = 0
3059pp_data->cap[64]->Units = 0
3060pp_data->cap[64]->UnitsExp = 0
3061
3062pp_data->cap[65]->UsagePage = 0xFF01
3063pp_data->cap[65]->ReportID = 0x02
3064pp_data->cap[65]->BitPosition = 0
3065pp_data->cap[65]->BitSize = 16
3066pp_data->cap[65]->ReportCount = 1
3067pp_data->cap[65]->BytePosition = 0x0029
3068pp_data->cap[65]->BitCount = 16
3069pp_data->cap[65]->BitField = 0x02
3070pp_data->cap[65]->NextBytePosition = 0x002B
3071pp_data->cap[65]->LinkCollection = 0x0002
3072pp_data->cap[65]->LinkUsagePage = 0xFF01
3073pp_data->cap[65]->LinkUsage = 0x0002
3074pp_data->cap[65]->IsMultipleItemsForArray = 0
3075pp_data->cap[65]->IsButtonCap = 0
3076pp_data->cap[65]->IsPadding = 0
3077pp_data->cap[65]->IsAbsolute = 1
3078pp_data->cap[65]->IsRange = 0
3079pp_data->cap[65]->IsAlias = 0
3080pp_data->cap[65]->IsStringRange = 0
3081pp_data->cap[65]->IsDesignatorRange = 0
3082pp_data->cap[65]->Reserved1 = 0x000000
3083pp_data->cap[65]->pp_cap->UnknownTokens[0].Token = 0x00
3084pp_data->cap[65]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3085pp_data->cap[65]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3086pp_data->cap[65]->pp_cap->UnknownTokens[1].Token = 0x00
3087pp_data->cap[65]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3088pp_data->cap[65]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3089pp_data->cap[65]->pp_cap->UnknownTokens[2].Token = 0x00
3090pp_data->cap[65]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3091pp_data->cap[65]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3092pp_data->cap[65]->pp_cap->UnknownTokens[3].Token = 0x00
3093pp_data->cap[65]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3094pp_data->cap[65]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3095pp_data->cap[65]->NotRange.Usage = 0x0004
3096pp_data->cap[65]->NotRange.Reserved1 = 0x0004
3097pp_data->cap[65]->NotRange.StringIndex = 0
3098pp_data->cap[65]->NotRange.Reserved2 = 0
3099pp_data->cap[65]->NotRange.DesignatorIndex = 0
3100pp_data->cap[65]->NotRange.Reserved3 = 0
3101pp_data->cap[65]->NotRange.DataIndex = 65
3102pp_data->cap[65]->NotRange.Reserved4 = 65
3103pp_data->cap[65]->NotButton.HasNull = 0
3104pp_data->cap[65]->NotButton.Reserved4 = 0x000000
3105pp_data->cap[65]->NotButton.LogicalMin = 0
3106pp_data->cap[65]->NotButton.LogicalMax = 4095
3107pp_data->cap[65]->NotButton.PhysicalMin = 0
3108pp_data->cap[65]->NotButton.PhysicalMax = 0
3109pp_data->cap[65]->Units = 0
3110pp_data->cap[65]->UnitsExp = 0
3111
3112pp_data->cap[66]->UsagePage = 0xFF01
3113pp_data->cap[66]->ReportID = 0x02
3114pp_data->cap[66]->BitPosition = 0
3115pp_data->cap[66]->BitSize = 16
3116pp_data->cap[66]->ReportCount = 1
3117pp_data->cap[66]->BytePosition = 0x0027
3118pp_data->cap[66]->BitCount = 16
3119pp_data->cap[66]->BitField = 0x02
3120pp_data->cap[66]->NextBytePosition = 0x0029
3121pp_data->cap[66]->LinkCollection = 0x0002
3122pp_data->cap[66]->LinkUsagePage = 0xFF01
3123pp_data->cap[66]->LinkUsage = 0x0002
3124pp_data->cap[66]->IsMultipleItemsForArray = 0
3125pp_data->cap[66]->IsButtonCap = 0
3126pp_data->cap[66]->IsPadding = 0
3127pp_data->cap[66]->IsAbsolute = 1
3128pp_data->cap[66]->IsRange = 0
3129pp_data->cap[66]->IsAlias = 0
3130pp_data->cap[66]->IsStringRange = 0
3131pp_data->cap[66]->IsDesignatorRange = 0
3132pp_data->cap[66]->Reserved1 = 0x000000
3133pp_data->cap[66]->pp_cap->UnknownTokens[0].Token = 0x00
3134pp_data->cap[66]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3135pp_data->cap[66]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3136pp_data->cap[66]->pp_cap->UnknownTokens[1].Token = 0x00
3137pp_data->cap[66]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3138pp_data->cap[66]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3139pp_data->cap[66]->pp_cap->UnknownTokens[2].Token = 0x00
3140pp_data->cap[66]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3141pp_data->cap[66]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3142pp_data->cap[66]->pp_cap->UnknownTokens[3].Token = 0x00
3143pp_data->cap[66]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3144pp_data->cap[66]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3145pp_data->cap[66]->NotRange.Usage = 0x0004
3146pp_data->cap[66]->NotRange.Reserved1 = 0x0004
3147pp_data->cap[66]->NotRange.StringIndex = 0
3148pp_data->cap[66]->NotRange.Reserved2 = 0
3149pp_data->cap[66]->NotRange.DesignatorIndex = 0
3150pp_data->cap[66]->NotRange.Reserved3 = 0
3151pp_data->cap[66]->NotRange.DataIndex = 66
3152pp_data->cap[66]->NotRange.Reserved4 = 66
3153pp_data->cap[66]->NotButton.HasNull = 0
3154pp_data->cap[66]->NotButton.Reserved4 = 0x000000
3155pp_data->cap[66]->NotButton.LogicalMin = 0
3156pp_data->cap[66]->NotButton.LogicalMax = 4095
3157pp_data->cap[66]->NotButton.PhysicalMin = 0
3158pp_data->cap[66]->NotButton.PhysicalMax = 0
3159pp_data->cap[66]->Units = 0
3160pp_data->cap[66]->UnitsExp = 0
3161
3162pp_data->cap[67]->UsagePage = 0xFF01
3163pp_data->cap[67]->ReportID = 0x02
3164pp_data->cap[67]->BitPosition = 0
3165pp_data->cap[67]->BitSize = 16
3166pp_data->cap[67]->ReportCount = 1
3167pp_data->cap[67]->BytePosition = 0x0025
3168pp_data->cap[67]->BitCount = 16
3169pp_data->cap[67]->BitField = 0x02
3170pp_data->cap[67]->NextBytePosition = 0x0027
3171pp_data->cap[67]->LinkCollection = 0x0002
3172pp_data->cap[67]->LinkUsagePage = 0xFF01
3173pp_data->cap[67]->LinkUsage = 0x0002
3174pp_data->cap[67]->IsMultipleItemsForArray = 0
3175pp_data->cap[67]->IsButtonCap = 0
3176pp_data->cap[67]->IsPadding = 0
3177pp_data->cap[67]->IsAbsolute = 1
3178pp_data->cap[67]->IsRange = 0
3179pp_data->cap[67]->IsAlias = 0
3180pp_data->cap[67]->IsStringRange = 0
3181pp_data->cap[67]->IsDesignatorRange = 0
3182pp_data->cap[67]->Reserved1 = 0x000000
3183pp_data->cap[67]->pp_cap->UnknownTokens[0].Token = 0x00
3184pp_data->cap[67]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3185pp_data->cap[67]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3186pp_data->cap[67]->pp_cap->UnknownTokens[1].Token = 0x00
3187pp_data->cap[67]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3188pp_data->cap[67]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3189pp_data->cap[67]->pp_cap->UnknownTokens[2].Token = 0x00
3190pp_data->cap[67]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3191pp_data->cap[67]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3192pp_data->cap[67]->pp_cap->UnknownTokens[3].Token = 0x00
3193pp_data->cap[67]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3194pp_data->cap[67]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3195pp_data->cap[67]->NotRange.Usage = 0x0004
3196pp_data->cap[67]->NotRange.Reserved1 = 0x0004
3197pp_data->cap[67]->NotRange.StringIndex = 0
3198pp_data->cap[67]->NotRange.Reserved2 = 0
3199pp_data->cap[67]->NotRange.DesignatorIndex = 0
3200pp_data->cap[67]->NotRange.Reserved3 = 0
3201pp_data->cap[67]->NotRange.DataIndex = 67
3202pp_data->cap[67]->NotRange.Reserved4 = 67
3203pp_data->cap[67]->NotButton.HasNull = 0
3204pp_data->cap[67]->NotButton.Reserved4 = 0x000000
3205pp_data->cap[67]->NotButton.LogicalMin = 0
3206pp_data->cap[67]->NotButton.LogicalMax = 4095
3207pp_data->cap[67]->NotButton.PhysicalMin = 0
3208pp_data->cap[67]->NotButton.PhysicalMax = 0
3209pp_data->cap[67]->Units = 0
3210pp_data->cap[67]->UnitsExp = 0
3211
3212pp_data->cap[68]->UsagePage = 0xFF01
3213pp_data->cap[68]->ReportID = 0x02
3214pp_data->cap[68]->BitPosition = 0
3215pp_data->cap[68]->BitSize = 16
3216pp_data->cap[68]->ReportCount = 1
3217pp_data->cap[68]->BytePosition = 0x0023
3218pp_data->cap[68]->BitCount = 16
3219pp_data->cap[68]->BitField = 0x02
3220pp_data->cap[68]->NextBytePosition = 0x0025
3221pp_data->cap[68]->LinkCollection = 0x0002
3222pp_data->cap[68]->LinkUsagePage = 0xFF01
3223pp_data->cap[68]->LinkUsage = 0x0002
3224pp_data->cap[68]->IsMultipleItemsForArray = 0
3225pp_data->cap[68]->IsButtonCap = 0
3226pp_data->cap[68]->IsPadding = 0
3227pp_data->cap[68]->IsAbsolute = 1
3228pp_data->cap[68]->IsRange = 0
3229pp_data->cap[68]->IsAlias = 0
3230pp_data->cap[68]->IsStringRange = 0
3231pp_data->cap[68]->IsDesignatorRange = 0
3232pp_data->cap[68]->Reserved1 = 0x000000
3233pp_data->cap[68]->pp_cap->UnknownTokens[0].Token = 0x00
3234pp_data->cap[68]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3235pp_data->cap[68]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3236pp_data->cap[68]->pp_cap->UnknownTokens[1].Token = 0x00
3237pp_data->cap[68]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3238pp_data->cap[68]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3239pp_data->cap[68]->pp_cap->UnknownTokens[2].Token = 0x00
3240pp_data->cap[68]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3241pp_data->cap[68]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3242pp_data->cap[68]->pp_cap->UnknownTokens[3].Token = 0x00
3243pp_data->cap[68]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3244pp_data->cap[68]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3245pp_data->cap[68]->NotRange.Usage = 0x0004
3246pp_data->cap[68]->NotRange.Reserved1 = 0x0004
3247pp_data->cap[68]->NotRange.StringIndex = 0
3248pp_data->cap[68]->NotRange.Reserved2 = 0
3249pp_data->cap[68]->NotRange.DesignatorIndex = 0
3250pp_data->cap[68]->NotRange.Reserved3 = 0
3251pp_data->cap[68]->NotRange.DataIndex = 68
3252pp_data->cap[68]->NotRange.Reserved4 = 68
3253pp_data->cap[68]->NotButton.HasNull = 0
3254pp_data->cap[68]->NotButton.Reserved4 = 0x000000
3255pp_data->cap[68]->NotButton.LogicalMin = 0
3256pp_data->cap[68]->NotButton.LogicalMax = 4095
3257pp_data->cap[68]->NotButton.PhysicalMin = 0
3258pp_data->cap[68]->NotButton.PhysicalMax = 0
3259pp_data->cap[68]->Units = 0
3260pp_data->cap[68]->UnitsExp = 0
3261
3262pp_data->cap[69]->UsagePage = 0xFF01
3263pp_data->cap[69]->ReportID = 0x02
3264pp_data->cap[69]->BitPosition = 0
3265pp_data->cap[69]->BitSize = 16
3266pp_data->cap[69]->ReportCount = 1
3267pp_data->cap[69]->BytePosition = 0x0021
3268pp_data->cap[69]->BitCount = 16
3269pp_data->cap[69]->BitField = 0x02
3270pp_data->cap[69]->NextBytePosition = 0x0023
3271pp_data->cap[69]->LinkCollection = 0x0002
3272pp_data->cap[69]->LinkUsagePage = 0xFF01
3273pp_data->cap[69]->LinkUsage = 0x0002
3274pp_data->cap[69]->IsMultipleItemsForArray = 0
3275pp_data->cap[69]->IsButtonCap = 0
3276pp_data->cap[69]->IsPadding = 0
3277pp_data->cap[69]->IsAbsolute = 1
3278pp_data->cap[69]->IsRange = 0
3279pp_data->cap[69]->IsAlias = 0
3280pp_data->cap[69]->IsStringRange = 0
3281pp_data->cap[69]->IsDesignatorRange = 0
3282pp_data->cap[69]->Reserved1 = 0x000000
3283pp_data->cap[69]->pp_cap->UnknownTokens[0].Token = 0x00
3284pp_data->cap[69]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3285pp_data->cap[69]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3286pp_data->cap[69]->pp_cap->UnknownTokens[1].Token = 0x00
3287pp_data->cap[69]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3288pp_data->cap[69]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3289pp_data->cap[69]->pp_cap->UnknownTokens[2].Token = 0x00
3290pp_data->cap[69]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3291pp_data->cap[69]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3292pp_data->cap[69]->pp_cap->UnknownTokens[3].Token = 0x00
3293pp_data->cap[69]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3294pp_data->cap[69]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3295pp_data->cap[69]->NotRange.Usage = 0x0004
3296pp_data->cap[69]->NotRange.Reserved1 = 0x0004
3297pp_data->cap[69]->NotRange.StringIndex = 0
3298pp_data->cap[69]->NotRange.Reserved2 = 0
3299pp_data->cap[69]->NotRange.DesignatorIndex = 0
3300pp_data->cap[69]->NotRange.Reserved3 = 0
3301pp_data->cap[69]->NotRange.DataIndex = 69
3302pp_data->cap[69]->NotRange.Reserved4 = 69
3303pp_data->cap[69]->NotButton.HasNull = 0
3304pp_data->cap[69]->NotButton.Reserved4 = 0x000000
3305pp_data->cap[69]->NotButton.LogicalMin = 0
3306pp_data->cap[69]->NotButton.LogicalMax = 4095
3307pp_data->cap[69]->NotButton.PhysicalMin = 0
3308pp_data->cap[69]->NotButton.PhysicalMax = 0
3309pp_data->cap[69]->Units = 0
3310pp_data->cap[69]->UnitsExp = 0
3311
3312pp_data->cap[70]->UsagePage = 0xFF01
3313pp_data->cap[70]->ReportID = 0x02
3314pp_data->cap[70]->BitPosition = 0
3315pp_data->cap[70]->BitSize = 16
3316pp_data->cap[70]->ReportCount = 1
3317pp_data->cap[70]->BytePosition = 0x001F
3318pp_data->cap[70]->BitCount = 16
3319pp_data->cap[70]->BitField = 0x02
3320pp_data->cap[70]->NextBytePosition = 0x0021
3321pp_data->cap[70]->LinkCollection = 0x0002
3322pp_data->cap[70]->LinkUsagePage = 0xFF01
3323pp_data->cap[70]->LinkUsage = 0x0002
3324pp_data->cap[70]->IsMultipleItemsForArray = 0
3325pp_data->cap[70]->IsButtonCap = 0
3326pp_data->cap[70]->IsPadding = 0
3327pp_data->cap[70]->IsAbsolute = 1
3328pp_data->cap[70]->IsRange = 0
3329pp_data->cap[70]->IsAlias = 0
3330pp_data->cap[70]->IsStringRange = 0
3331pp_data->cap[70]->IsDesignatorRange = 0
3332pp_data->cap[70]->Reserved1 = 0x000000
3333pp_data->cap[70]->pp_cap->UnknownTokens[0].Token = 0x00
3334pp_data->cap[70]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3335pp_data->cap[70]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3336pp_data->cap[70]->pp_cap->UnknownTokens[1].Token = 0x00
3337pp_data->cap[70]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3338pp_data->cap[70]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3339pp_data->cap[70]->pp_cap->UnknownTokens[2].Token = 0x00
3340pp_data->cap[70]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3341pp_data->cap[70]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3342pp_data->cap[70]->pp_cap->UnknownTokens[3].Token = 0x00
3343pp_data->cap[70]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3344pp_data->cap[70]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3345pp_data->cap[70]->NotRange.Usage = 0x0004
3346pp_data->cap[70]->NotRange.Reserved1 = 0x0004
3347pp_data->cap[70]->NotRange.StringIndex = 0
3348pp_data->cap[70]->NotRange.Reserved2 = 0
3349pp_data->cap[70]->NotRange.DesignatorIndex = 0
3350pp_data->cap[70]->NotRange.Reserved3 = 0
3351pp_data->cap[70]->NotRange.DataIndex = 70
3352pp_data->cap[70]->NotRange.Reserved4 = 70
3353pp_data->cap[70]->NotButton.HasNull = 0
3354pp_data->cap[70]->NotButton.Reserved4 = 0x000000
3355pp_data->cap[70]->NotButton.LogicalMin = 0
3356pp_data->cap[70]->NotButton.LogicalMax = 4095
3357pp_data->cap[70]->NotButton.PhysicalMin = 0
3358pp_data->cap[70]->NotButton.PhysicalMax = 0
3359pp_data->cap[70]->Units = 0
3360pp_data->cap[70]->UnitsExp = 0
3361
3362pp_data->cap[71]->UsagePage = 0xFF01
3363pp_data->cap[71]->ReportID = 0x02
3364pp_data->cap[71]->BitPosition = 0
3365pp_data->cap[71]->BitSize = 16
3366pp_data->cap[71]->ReportCount = 1
3367pp_data->cap[71]->BytePosition = 0x001D
3368pp_data->cap[71]->BitCount = 16
3369pp_data->cap[71]->BitField = 0x02
3370pp_data->cap[71]->NextBytePosition = 0x001F
3371pp_data->cap[71]->LinkCollection = 0x0002
3372pp_data->cap[71]->LinkUsagePage = 0xFF01
3373pp_data->cap[71]->LinkUsage = 0x0002
3374pp_data->cap[71]->IsMultipleItemsForArray = 0
3375pp_data->cap[71]->IsButtonCap = 0
3376pp_data->cap[71]->IsPadding = 0
3377pp_data->cap[71]->IsAbsolute = 1
3378pp_data->cap[71]->IsRange = 0
3379pp_data->cap[71]->IsAlias = 0
3380pp_data->cap[71]->IsStringRange = 0
3381pp_data->cap[71]->IsDesignatorRange = 0
3382pp_data->cap[71]->Reserved1 = 0x000000
3383pp_data->cap[71]->pp_cap->UnknownTokens[0].Token = 0x00
3384pp_data->cap[71]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3385pp_data->cap[71]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3386pp_data->cap[71]->pp_cap->UnknownTokens[1].Token = 0x00
3387pp_data->cap[71]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3388pp_data->cap[71]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3389pp_data->cap[71]->pp_cap->UnknownTokens[2].Token = 0x00
3390pp_data->cap[71]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3391pp_data->cap[71]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3392pp_data->cap[71]->pp_cap->UnknownTokens[3].Token = 0x00
3393pp_data->cap[71]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3394pp_data->cap[71]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3395pp_data->cap[71]->NotRange.Usage = 0x0004
3396pp_data->cap[71]->NotRange.Reserved1 = 0x0004
3397pp_data->cap[71]->NotRange.StringIndex = 0
3398pp_data->cap[71]->NotRange.Reserved2 = 0
3399pp_data->cap[71]->NotRange.DesignatorIndex = 0
3400pp_data->cap[71]->NotRange.Reserved3 = 0
3401pp_data->cap[71]->NotRange.DataIndex = 71
3402pp_data->cap[71]->NotRange.Reserved4 = 71
3403pp_data->cap[71]->NotButton.HasNull = 0
3404pp_data->cap[71]->NotButton.Reserved4 = 0x000000
3405pp_data->cap[71]->NotButton.LogicalMin = 0
3406pp_data->cap[71]->NotButton.LogicalMax = 4095
3407pp_data->cap[71]->NotButton.PhysicalMin = 0
3408pp_data->cap[71]->NotButton.PhysicalMax = 0
3409pp_data->cap[71]->Units = 0
3410pp_data->cap[71]->UnitsExp = 0
3411
3412pp_data->cap[72]->UsagePage = 0xFF01
3413pp_data->cap[72]->ReportID = 0x02
3414pp_data->cap[72]->BitPosition = 0
3415pp_data->cap[72]->BitSize = 16
3416pp_data->cap[72]->ReportCount = 1
3417pp_data->cap[72]->BytePosition = 0x001B
3418pp_data->cap[72]->BitCount = 16
3419pp_data->cap[72]->BitField = 0x02
3420pp_data->cap[72]->NextBytePosition = 0x001D
3421pp_data->cap[72]->LinkCollection = 0x0002
3422pp_data->cap[72]->LinkUsagePage = 0xFF01
3423pp_data->cap[72]->LinkUsage = 0x0002
3424pp_data->cap[72]->IsMultipleItemsForArray = 0
3425pp_data->cap[72]->IsButtonCap = 0
3426pp_data->cap[72]->IsPadding = 0
3427pp_data->cap[72]->IsAbsolute = 1
3428pp_data->cap[72]->IsRange = 0
3429pp_data->cap[72]->IsAlias = 0
3430pp_data->cap[72]->IsStringRange = 0
3431pp_data->cap[72]->IsDesignatorRange = 0
3432pp_data->cap[72]->Reserved1 = 0x000000
3433pp_data->cap[72]->pp_cap->UnknownTokens[0].Token = 0x00
3434pp_data->cap[72]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3435pp_data->cap[72]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3436pp_data->cap[72]->pp_cap->UnknownTokens[1].Token = 0x00
3437pp_data->cap[72]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3438pp_data->cap[72]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3439pp_data->cap[72]->pp_cap->UnknownTokens[2].Token = 0x00
3440pp_data->cap[72]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3441pp_data->cap[72]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3442pp_data->cap[72]->pp_cap->UnknownTokens[3].Token = 0x00
3443pp_data->cap[72]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3444pp_data->cap[72]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3445pp_data->cap[72]->NotRange.Usage = 0x0004
3446pp_data->cap[72]->NotRange.Reserved1 = 0x0004
3447pp_data->cap[72]->NotRange.StringIndex = 0
3448pp_data->cap[72]->NotRange.Reserved2 = 0
3449pp_data->cap[72]->NotRange.DesignatorIndex = 0
3450pp_data->cap[72]->NotRange.Reserved3 = 0
3451pp_data->cap[72]->NotRange.DataIndex = 72
3452pp_data->cap[72]->NotRange.Reserved4 = 72
3453pp_data->cap[72]->NotButton.HasNull = 0
3454pp_data->cap[72]->NotButton.Reserved4 = 0x000000
3455pp_data->cap[72]->NotButton.LogicalMin = 0
3456pp_data->cap[72]->NotButton.LogicalMax = 4095
3457pp_data->cap[72]->NotButton.PhysicalMin = 0
3458pp_data->cap[72]->NotButton.PhysicalMax = 0
3459pp_data->cap[72]->Units = 0
3460pp_data->cap[72]->UnitsExp = 0
3461
3462pp_data->cap[73]->UsagePage = 0xFF01
3463pp_data->cap[73]->ReportID = 0x02
3464pp_data->cap[73]->BitPosition = 0
3465pp_data->cap[73]->BitSize = 16
3466pp_data->cap[73]->ReportCount = 1
3467pp_data->cap[73]->BytePosition = 0x0019
3468pp_data->cap[73]->BitCount = 16
3469pp_data->cap[73]->BitField = 0x02
3470pp_data->cap[73]->NextBytePosition = 0x001B
3471pp_data->cap[73]->LinkCollection = 0x0002
3472pp_data->cap[73]->LinkUsagePage = 0xFF01
3473pp_data->cap[73]->LinkUsage = 0x0002
3474pp_data->cap[73]->IsMultipleItemsForArray = 0
3475pp_data->cap[73]->IsButtonCap = 0
3476pp_data->cap[73]->IsPadding = 0
3477pp_data->cap[73]->IsAbsolute = 1
3478pp_data->cap[73]->IsRange = 0
3479pp_data->cap[73]->IsAlias = 0
3480pp_data->cap[73]->IsStringRange = 0
3481pp_data->cap[73]->IsDesignatorRange = 0
3482pp_data->cap[73]->Reserved1 = 0x000000
3483pp_data->cap[73]->pp_cap->UnknownTokens[0].Token = 0x00
3484pp_data->cap[73]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3485pp_data->cap[73]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3486pp_data->cap[73]->pp_cap->UnknownTokens[1].Token = 0x00
3487pp_data->cap[73]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3488pp_data->cap[73]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3489pp_data->cap[73]->pp_cap->UnknownTokens[2].Token = 0x00
3490pp_data->cap[73]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3491pp_data->cap[73]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3492pp_data->cap[73]->pp_cap->UnknownTokens[3].Token = 0x00
3493pp_data->cap[73]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3494pp_data->cap[73]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3495pp_data->cap[73]->NotRange.Usage = 0x0004
3496pp_data->cap[73]->NotRange.Reserved1 = 0x0004
3497pp_data->cap[73]->NotRange.StringIndex = 0
3498pp_data->cap[73]->NotRange.Reserved2 = 0
3499pp_data->cap[73]->NotRange.DesignatorIndex = 0
3500pp_data->cap[73]->NotRange.Reserved3 = 0
3501pp_data->cap[73]->NotRange.DataIndex = 73
3502pp_data->cap[73]->NotRange.Reserved4 = 73
3503pp_data->cap[73]->NotButton.HasNull = 0
3504pp_data->cap[73]->NotButton.Reserved4 = 0x000000
3505pp_data->cap[73]->NotButton.LogicalMin = 0
3506pp_data->cap[73]->NotButton.LogicalMax = 4095
3507pp_data->cap[73]->NotButton.PhysicalMin = 0
3508pp_data->cap[73]->NotButton.PhysicalMax = 0
3509pp_data->cap[73]->Units = 0
3510pp_data->cap[73]->UnitsExp = 0
3511
3512pp_data->cap[74]->UsagePage = 0xFF01
3513pp_data->cap[74]->ReportID = 0x02
3514pp_data->cap[74]->BitPosition = 0
3515pp_data->cap[74]->BitSize = 16
3516pp_data->cap[74]->ReportCount = 1
3517pp_data->cap[74]->BytePosition = 0x0017
3518pp_data->cap[74]->BitCount = 16
3519pp_data->cap[74]->BitField = 0x02
3520pp_data->cap[74]->NextBytePosition = 0x0019
3521pp_data->cap[74]->LinkCollection = 0x0002
3522pp_data->cap[74]->LinkUsagePage = 0xFF01
3523pp_data->cap[74]->LinkUsage = 0x0002
3524pp_data->cap[74]->IsMultipleItemsForArray = 0
3525pp_data->cap[74]->IsButtonCap = 0
3526pp_data->cap[74]->IsPadding = 0
3527pp_data->cap[74]->IsAbsolute = 1
3528pp_data->cap[74]->IsRange = 0
3529pp_data->cap[74]->IsAlias = 0
3530pp_data->cap[74]->IsStringRange = 0
3531pp_data->cap[74]->IsDesignatorRange = 0
3532pp_data->cap[74]->Reserved1 = 0x000000
3533pp_data->cap[74]->pp_cap->UnknownTokens[0].Token = 0x00
3534pp_data->cap[74]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3535pp_data->cap[74]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3536pp_data->cap[74]->pp_cap->UnknownTokens[1].Token = 0x00
3537pp_data->cap[74]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3538pp_data->cap[74]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3539pp_data->cap[74]->pp_cap->UnknownTokens[2].Token = 0x00
3540pp_data->cap[74]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3541pp_data->cap[74]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3542pp_data->cap[74]->pp_cap->UnknownTokens[3].Token = 0x00
3543pp_data->cap[74]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3544pp_data->cap[74]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3545pp_data->cap[74]->NotRange.Usage = 0x0004
3546pp_data->cap[74]->NotRange.Reserved1 = 0x0004
3547pp_data->cap[74]->NotRange.StringIndex = 0
3548pp_data->cap[74]->NotRange.Reserved2 = 0
3549pp_data->cap[74]->NotRange.DesignatorIndex = 0
3550pp_data->cap[74]->NotRange.Reserved3 = 0
3551pp_data->cap[74]->NotRange.DataIndex = 74
3552pp_data->cap[74]->NotRange.Reserved4 = 74
3553pp_data->cap[74]->NotButton.HasNull = 0
3554pp_data->cap[74]->NotButton.Reserved4 = 0x000000
3555pp_data->cap[74]->NotButton.LogicalMin = 0
3556pp_data->cap[74]->NotButton.LogicalMax = 4095
3557pp_data->cap[74]->NotButton.PhysicalMin = 0
3558pp_data->cap[74]->NotButton.PhysicalMax = 0
3559pp_data->cap[74]->Units = 0
3560pp_data->cap[74]->UnitsExp = 0
3561
3562pp_data->cap[75]->UsagePage = 0xFF01
3563pp_data->cap[75]->ReportID = 0x02
3564pp_data->cap[75]->BitPosition = 0
3565pp_data->cap[75]->BitSize = 16
3566pp_data->cap[75]->ReportCount = 1
3567pp_data->cap[75]->BytePosition = 0x0015
3568pp_data->cap[75]->BitCount = 16
3569pp_data->cap[75]->BitField = 0x02
3570pp_data->cap[75]->NextBytePosition = 0x0017
3571pp_data->cap[75]->LinkCollection = 0x0002
3572pp_data->cap[75]->LinkUsagePage = 0xFF01
3573pp_data->cap[75]->LinkUsage = 0x0002
3574pp_data->cap[75]->IsMultipleItemsForArray = 0
3575pp_data->cap[75]->IsButtonCap = 0
3576pp_data->cap[75]->IsPadding = 0
3577pp_data->cap[75]->IsAbsolute = 1
3578pp_data->cap[75]->IsRange = 0
3579pp_data->cap[75]->IsAlias = 0
3580pp_data->cap[75]->IsStringRange = 0
3581pp_data->cap[75]->IsDesignatorRange = 0
3582pp_data->cap[75]->Reserved1 = 0x000000
3583pp_data->cap[75]->pp_cap->UnknownTokens[0].Token = 0x00
3584pp_data->cap[75]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3585pp_data->cap[75]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3586pp_data->cap[75]->pp_cap->UnknownTokens[1].Token = 0x00
3587pp_data->cap[75]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3588pp_data->cap[75]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3589pp_data->cap[75]->pp_cap->UnknownTokens[2].Token = 0x00
3590pp_data->cap[75]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3591pp_data->cap[75]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3592pp_data->cap[75]->pp_cap->UnknownTokens[3].Token = 0x00
3593pp_data->cap[75]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3594pp_data->cap[75]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3595pp_data->cap[75]->NotRange.Usage = 0x0004
3596pp_data->cap[75]->NotRange.Reserved1 = 0x0004
3597pp_data->cap[75]->NotRange.StringIndex = 0
3598pp_data->cap[75]->NotRange.Reserved2 = 0
3599pp_data->cap[75]->NotRange.DesignatorIndex = 0
3600pp_data->cap[75]->NotRange.Reserved3 = 0
3601pp_data->cap[75]->NotRange.DataIndex = 75
3602pp_data->cap[75]->NotRange.Reserved4 = 75
3603pp_data->cap[75]->NotButton.HasNull = 0
3604pp_data->cap[75]->NotButton.Reserved4 = 0x000000
3605pp_data->cap[75]->NotButton.LogicalMin = 0
3606pp_data->cap[75]->NotButton.LogicalMax = 4095
3607pp_data->cap[75]->NotButton.PhysicalMin = 0
3608pp_data->cap[75]->NotButton.PhysicalMax = 0
3609pp_data->cap[75]->Units = 0
3610pp_data->cap[75]->UnitsExp = 0
3611
3612pp_data->cap[76]->UsagePage = 0xFF01
3613pp_data->cap[76]->ReportID = 0x02
3614pp_data->cap[76]->BitPosition = 0
3615pp_data->cap[76]->BitSize = 16
3616pp_data->cap[76]->ReportCount = 1
3617pp_data->cap[76]->BytePosition = 0x0013
3618pp_data->cap[76]->BitCount = 16
3619pp_data->cap[76]->BitField = 0x02
3620pp_data->cap[76]->NextBytePosition = 0x0015
3621pp_data->cap[76]->LinkCollection = 0x0002
3622pp_data->cap[76]->LinkUsagePage = 0xFF01
3623pp_data->cap[76]->LinkUsage = 0x0002
3624pp_data->cap[76]->IsMultipleItemsForArray = 0
3625pp_data->cap[76]->IsButtonCap = 0
3626pp_data->cap[76]->IsPadding = 0
3627pp_data->cap[76]->IsAbsolute = 1
3628pp_data->cap[76]->IsRange = 0
3629pp_data->cap[76]->IsAlias = 0
3630pp_data->cap[76]->IsStringRange = 0
3631pp_data->cap[76]->IsDesignatorRange = 0
3632pp_data->cap[76]->Reserved1 = 0x000000
3633pp_data->cap[76]->pp_cap->UnknownTokens[0].Token = 0x00
3634pp_data->cap[76]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3635pp_data->cap[76]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3636pp_data->cap[76]->pp_cap->UnknownTokens[1].Token = 0x00
3637pp_data->cap[76]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3638pp_data->cap[76]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3639pp_data->cap[76]->pp_cap->UnknownTokens[2].Token = 0x00
3640pp_data->cap[76]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3641pp_data->cap[76]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3642pp_data->cap[76]->pp_cap->UnknownTokens[3].Token = 0x00
3643pp_data->cap[76]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3644pp_data->cap[76]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3645pp_data->cap[76]->NotRange.Usage = 0x0004
3646pp_data->cap[76]->NotRange.Reserved1 = 0x0004
3647pp_data->cap[76]->NotRange.StringIndex = 0
3648pp_data->cap[76]->NotRange.Reserved2 = 0
3649pp_data->cap[76]->NotRange.DesignatorIndex = 0
3650pp_data->cap[76]->NotRange.Reserved3 = 0
3651pp_data->cap[76]->NotRange.DataIndex = 76
3652pp_data->cap[76]->NotRange.Reserved4 = 76
3653pp_data->cap[76]->NotButton.HasNull = 0
3654pp_data->cap[76]->NotButton.Reserved4 = 0x000000
3655pp_data->cap[76]->NotButton.LogicalMin = 0
3656pp_data->cap[76]->NotButton.LogicalMax = 4095
3657pp_data->cap[76]->NotButton.PhysicalMin = 0
3658pp_data->cap[76]->NotButton.PhysicalMax = 0
3659pp_data->cap[76]->Units = 0
3660pp_data->cap[76]->UnitsExp = 0
3661
3662pp_data->cap[77]->UsagePage = 0xFF01
3663pp_data->cap[77]->ReportID = 0x02
3664pp_data->cap[77]->BitPosition = 0
3665pp_data->cap[77]->BitSize = 16
3666pp_data->cap[77]->ReportCount = 1
3667pp_data->cap[77]->BytePosition = 0x0011
3668pp_data->cap[77]->BitCount = 16
3669pp_data->cap[77]->BitField = 0x02
3670pp_data->cap[77]->NextBytePosition = 0x0013
3671pp_data->cap[77]->LinkCollection = 0x0002
3672pp_data->cap[77]->LinkUsagePage = 0xFF01
3673pp_data->cap[77]->LinkUsage = 0x0002
3674pp_data->cap[77]->IsMultipleItemsForArray = 0
3675pp_data->cap[77]->IsButtonCap = 0
3676pp_data->cap[77]->IsPadding = 0
3677pp_data->cap[77]->IsAbsolute = 1
3678pp_data->cap[77]->IsRange = 0
3679pp_data->cap[77]->IsAlias = 0
3680pp_data->cap[77]->IsStringRange = 0
3681pp_data->cap[77]->IsDesignatorRange = 0
3682pp_data->cap[77]->Reserved1 = 0x000000
3683pp_data->cap[77]->pp_cap->UnknownTokens[0].Token = 0x00
3684pp_data->cap[77]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3685pp_data->cap[77]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3686pp_data->cap[77]->pp_cap->UnknownTokens[1].Token = 0x00
3687pp_data->cap[77]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3688pp_data->cap[77]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3689pp_data->cap[77]->pp_cap->UnknownTokens[2].Token = 0x00
3690pp_data->cap[77]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3691pp_data->cap[77]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3692pp_data->cap[77]->pp_cap->UnknownTokens[3].Token = 0x00
3693pp_data->cap[77]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3694pp_data->cap[77]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3695pp_data->cap[77]->NotRange.Usage = 0x0004
3696pp_data->cap[77]->NotRange.Reserved1 = 0x0004
3697pp_data->cap[77]->NotRange.StringIndex = 0
3698pp_data->cap[77]->NotRange.Reserved2 = 0
3699pp_data->cap[77]->NotRange.DesignatorIndex = 0
3700pp_data->cap[77]->NotRange.Reserved3 = 0
3701pp_data->cap[77]->NotRange.DataIndex = 77
3702pp_data->cap[77]->NotRange.Reserved4 = 77
3703pp_data->cap[77]->NotButton.HasNull = 0
3704pp_data->cap[77]->NotButton.Reserved4 = 0x000000
3705pp_data->cap[77]->NotButton.LogicalMin = 0
3706pp_data->cap[77]->NotButton.LogicalMax = 4095
3707pp_data->cap[77]->NotButton.PhysicalMin = 0
3708pp_data->cap[77]->NotButton.PhysicalMax = 0
3709pp_data->cap[77]->Units = 0
3710pp_data->cap[77]->UnitsExp = 0
3711
3712pp_data->cap[78]->UsagePage = 0xFF01
3713pp_data->cap[78]->ReportID = 0x02
3714pp_data->cap[78]->BitPosition = 0
3715pp_data->cap[78]->BitSize = 16
3716pp_data->cap[78]->ReportCount = 1
3717pp_data->cap[78]->BytePosition = 0x000F
3718pp_data->cap[78]->BitCount = 16
3719pp_data->cap[78]->BitField = 0x02
3720pp_data->cap[78]->NextBytePosition = 0x0011
3721pp_data->cap[78]->LinkCollection = 0x0002
3722pp_data->cap[78]->LinkUsagePage = 0xFF01
3723pp_data->cap[78]->LinkUsage = 0x0002
3724pp_data->cap[78]->IsMultipleItemsForArray = 0
3725pp_data->cap[78]->IsButtonCap = 0
3726pp_data->cap[78]->IsPadding = 0
3727pp_data->cap[78]->IsAbsolute = 1
3728pp_data->cap[78]->IsRange = 0
3729pp_data->cap[78]->IsAlias = 0
3730pp_data->cap[78]->IsStringRange = 0
3731pp_data->cap[78]->IsDesignatorRange = 0
3732pp_data->cap[78]->Reserved1 = 0x000000
3733pp_data->cap[78]->pp_cap->UnknownTokens[0].Token = 0x00
3734pp_data->cap[78]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3735pp_data->cap[78]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3736pp_data->cap[78]->pp_cap->UnknownTokens[1].Token = 0x00
3737pp_data->cap[78]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3738pp_data->cap[78]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3739pp_data->cap[78]->pp_cap->UnknownTokens[2].Token = 0x00
3740pp_data->cap[78]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3741pp_data->cap[78]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3742pp_data->cap[78]->pp_cap->UnknownTokens[3].Token = 0x00
3743pp_data->cap[78]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3744pp_data->cap[78]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3745pp_data->cap[78]->NotRange.Usage = 0x0004
3746pp_data->cap[78]->NotRange.Reserved1 = 0x0004
3747pp_data->cap[78]->NotRange.StringIndex = 0
3748pp_data->cap[78]->NotRange.Reserved2 = 0
3749pp_data->cap[78]->NotRange.DesignatorIndex = 0
3750pp_data->cap[78]->NotRange.Reserved3 = 0
3751pp_data->cap[78]->NotRange.DataIndex = 78
3752pp_data->cap[78]->NotRange.Reserved4 = 78
3753pp_data->cap[78]->NotButton.HasNull = 0
3754pp_data->cap[78]->NotButton.Reserved4 = 0x000000
3755pp_data->cap[78]->NotButton.LogicalMin = 0
3756pp_data->cap[78]->NotButton.LogicalMax = 4095
3757pp_data->cap[78]->NotButton.PhysicalMin = 0
3758pp_data->cap[78]->NotButton.PhysicalMax = 0
3759pp_data->cap[78]->Units = 0
3760pp_data->cap[78]->UnitsExp = 0
3761
3762pp_data->cap[79]->UsagePage = 0xFF01
3763pp_data->cap[79]->ReportID = 0x02
3764pp_data->cap[79]->BitPosition = 0
3765pp_data->cap[79]->BitSize = 16
3766pp_data->cap[79]->ReportCount = 1
3767pp_data->cap[79]->BytePosition = 0x000D
3768pp_data->cap[79]->BitCount = 16
3769pp_data->cap[79]->BitField = 0x02
3770pp_data->cap[79]->NextBytePosition = 0x000F
3771pp_data->cap[79]->LinkCollection = 0x0002
3772pp_data->cap[79]->LinkUsagePage = 0xFF01
3773pp_data->cap[79]->LinkUsage = 0x0002
3774pp_data->cap[79]->IsMultipleItemsForArray = 0
3775pp_data->cap[79]->IsButtonCap = 0
3776pp_data->cap[79]->IsPadding = 0
3777pp_data->cap[79]->IsAbsolute = 1
3778pp_data->cap[79]->IsRange = 0
3779pp_data->cap[79]->IsAlias = 0
3780pp_data->cap[79]->IsStringRange = 0
3781pp_data->cap[79]->IsDesignatorRange = 0
3782pp_data->cap[79]->Reserved1 = 0x000000
3783pp_data->cap[79]->pp_cap->UnknownTokens[0].Token = 0x00
3784pp_data->cap[79]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3785pp_data->cap[79]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3786pp_data->cap[79]->pp_cap->UnknownTokens[1].Token = 0x00
3787pp_data->cap[79]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3788pp_data->cap[79]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3789pp_data->cap[79]->pp_cap->UnknownTokens[2].Token = 0x00
3790pp_data->cap[79]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3791pp_data->cap[79]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3792pp_data->cap[79]->pp_cap->UnknownTokens[3].Token = 0x00
3793pp_data->cap[79]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3794pp_data->cap[79]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3795pp_data->cap[79]->NotRange.Usage = 0x0004
3796pp_data->cap[79]->NotRange.Reserved1 = 0x0004
3797pp_data->cap[79]->NotRange.StringIndex = 0
3798pp_data->cap[79]->NotRange.Reserved2 = 0
3799pp_data->cap[79]->NotRange.DesignatorIndex = 0
3800pp_data->cap[79]->NotRange.Reserved3 = 0
3801pp_data->cap[79]->NotRange.DataIndex = 79
3802pp_data->cap[79]->NotRange.Reserved4 = 79
3803pp_data->cap[79]->NotButton.HasNull = 0
3804pp_data->cap[79]->NotButton.Reserved4 = 0x000000
3805pp_data->cap[79]->NotButton.LogicalMin = 0
3806pp_data->cap[79]->NotButton.LogicalMax = 4095
3807pp_data->cap[79]->NotButton.PhysicalMin = 0
3808pp_data->cap[79]->NotButton.PhysicalMax = 0
3809pp_data->cap[79]->Units = 0
3810pp_data->cap[79]->UnitsExp = 0
3811
3812pp_data->cap[80]->UsagePage = 0xFF01
3813pp_data->cap[80]->ReportID = 0x02
3814pp_data->cap[80]->BitPosition = 0
3815pp_data->cap[80]->BitSize = 16
3816pp_data->cap[80]->ReportCount = 1
3817pp_data->cap[80]->BytePosition = 0x000B
3818pp_data->cap[80]->BitCount = 16
3819pp_data->cap[80]->BitField = 0x02
3820pp_data->cap[80]->NextBytePosition = 0x000D
3821pp_data->cap[80]->LinkCollection = 0x0002
3822pp_data->cap[80]->LinkUsagePage = 0xFF01
3823pp_data->cap[80]->LinkUsage = 0x0002
3824pp_data->cap[80]->IsMultipleItemsForArray = 0
3825pp_data->cap[80]->IsButtonCap = 0
3826pp_data->cap[80]->IsPadding = 0
3827pp_data->cap[80]->IsAbsolute = 1
3828pp_data->cap[80]->IsRange = 0
3829pp_data->cap[80]->IsAlias = 0
3830pp_data->cap[80]->IsStringRange = 0
3831pp_data->cap[80]->IsDesignatorRange = 0
3832pp_data->cap[80]->Reserved1 = 0x000000
3833pp_data->cap[80]->pp_cap->UnknownTokens[0].Token = 0x00
3834pp_data->cap[80]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3835pp_data->cap[80]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3836pp_data->cap[80]->pp_cap->UnknownTokens[1].Token = 0x00
3837pp_data->cap[80]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3838pp_data->cap[80]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3839pp_data->cap[80]->pp_cap->UnknownTokens[2].Token = 0x00
3840pp_data->cap[80]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3841pp_data->cap[80]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3842pp_data->cap[80]->pp_cap->UnknownTokens[3].Token = 0x00
3843pp_data->cap[80]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3844pp_data->cap[80]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3845pp_data->cap[80]->NotRange.Usage = 0x0004
3846pp_data->cap[80]->NotRange.Reserved1 = 0x0004
3847pp_data->cap[80]->NotRange.StringIndex = 0
3848pp_data->cap[80]->NotRange.Reserved2 = 0
3849pp_data->cap[80]->NotRange.DesignatorIndex = 0
3850pp_data->cap[80]->NotRange.Reserved3 = 0
3851pp_data->cap[80]->NotRange.DataIndex = 80
3852pp_data->cap[80]->NotRange.Reserved4 = 80
3853pp_data->cap[80]->NotButton.HasNull = 0
3854pp_data->cap[80]->NotButton.Reserved4 = 0x000000
3855pp_data->cap[80]->NotButton.LogicalMin = 0
3856pp_data->cap[80]->NotButton.LogicalMax = 4095
3857pp_data->cap[80]->NotButton.PhysicalMin = 0
3858pp_data->cap[80]->NotButton.PhysicalMax = 0
3859pp_data->cap[80]->Units = 0
3860pp_data->cap[80]->UnitsExp = 0
3861
3862pp_data->cap[81]->UsagePage = 0xFF01
3863pp_data->cap[81]->ReportID = 0x02
3864pp_data->cap[81]->BitPosition = 0
3865pp_data->cap[81]->BitSize = 16
3866pp_data->cap[81]->ReportCount = 1
3867pp_data->cap[81]->BytePosition = 0x0009
3868pp_data->cap[81]->BitCount = 16
3869pp_data->cap[81]->BitField = 0x02
3870pp_data->cap[81]->NextBytePosition = 0x000B
3871pp_data->cap[81]->LinkCollection = 0x0002
3872pp_data->cap[81]->LinkUsagePage = 0xFF01
3873pp_data->cap[81]->LinkUsage = 0x0002
3874pp_data->cap[81]->IsMultipleItemsForArray = 0
3875pp_data->cap[81]->IsButtonCap = 0
3876pp_data->cap[81]->IsPadding = 0
3877pp_data->cap[81]->IsAbsolute = 1
3878pp_data->cap[81]->IsRange = 0
3879pp_data->cap[81]->IsAlias = 0
3880pp_data->cap[81]->IsStringRange = 0
3881pp_data->cap[81]->IsDesignatorRange = 0
3882pp_data->cap[81]->Reserved1 = 0x000000
3883pp_data->cap[81]->pp_cap->UnknownTokens[0].Token = 0x00
3884pp_data->cap[81]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3885pp_data->cap[81]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3886pp_data->cap[81]->pp_cap->UnknownTokens[1].Token = 0x00
3887pp_data->cap[81]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3888pp_data->cap[81]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3889pp_data->cap[81]->pp_cap->UnknownTokens[2].Token = 0x00
3890pp_data->cap[81]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3891pp_data->cap[81]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3892pp_data->cap[81]->pp_cap->UnknownTokens[3].Token = 0x00
3893pp_data->cap[81]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3894pp_data->cap[81]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3895pp_data->cap[81]->NotRange.Usage = 0x0004
3896pp_data->cap[81]->NotRange.Reserved1 = 0x0004
3897pp_data->cap[81]->NotRange.StringIndex = 0
3898pp_data->cap[81]->NotRange.Reserved2 = 0
3899pp_data->cap[81]->NotRange.DesignatorIndex = 0
3900pp_data->cap[81]->NotRange.Reserved3 = 0
3901pp_data->cap[81]->NotRange.DataIndex = 81
3902pp_data->cap[81]->NotRange.Reserved4 = 81
3903pp_data->cap[81]->NotButton.HasNull = 0
3904pp_data->cap[81]->NotButton.Reserved4 = 0x000000
3905pp_data->cap[81]->NotButton.LogicalMin = 0
3906pp_data->cap[81]->NotButton.LogicalMax = 4095
3907pp_data->cap[81]->NotButton.PhysicalMin = 0
3908pp_data->cap[81]->NotButton.PhysicalMax = 0
3909pp_data->cap[81]->Units = 0
3910pp_data->cap[81]->UnitsExp = 0
3911
3912pp_data->cap[82]->UsagePage = 0xFF01
3913pp_data->cap[82]->ReportID = 0x02
3914pp_data->cap[82]->BitPosition = 0
3915pp_data->cap[82]->BitSize = 16
3916pp_data->cap[82]->ReportCount = 1
3917pp_data->cap[82]->BytePosition = 0x0007
3918pp_data->cap[82]->BitCount = 16
3919pp_data->cap[82]->BitField = 0x02
3920pp_data->cap[82]->NextBytePosition = 0x0009
3921pp_data->cap[82]->LinkCollection = 0x0002
3922pp_data->cap[82]->LinkUsagePage = 0xFF01
3923pp_data->cap[82]->LinkUsage = 0x0002
3924pp_data->cap[82]->IsMultipleItemsForArray = 0
3925pp_data->cap[82]->IsButtonCap = 0
3926pp_data->cap[82]->IsPadding = 0
3927pp_data->cap[82]->IsAbsolute = 1
3928pp_data->cap[82]->IsRange = 0
3929pp_data->cap[82]->IsAlias = 0
3930pp_data->cap[82]->IsStringRange = 0
3931pp_data->cap[82]->IsDesignatorRange = 0
3932pp_data->cap[82]->Reserved1 = 0x000000
3933pp_data->cap[82]->pp_cap->UnknownTokens[0].Token = 0x00
3934pp_data->cap[82]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3935pp_data->cap[82]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3936pp_data->cap[82]->pp_cap->UnknownTokens[1].Token = 0x00
3937pp_data->cap[82]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3938pp_data->cap[82]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3939pp_data->cap[82]->pp_cap->UnknownTokens[2].Token = 0x00
3940pp_data->cap[82]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3941pp_data->cap[82]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3942pp_data->cap[82]->pp_cap->UnknownTokens[3].Token = 0x00
3943pp_data->cap[82]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3944pp_data->cap[82]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3945pp_data->cap[82]->NotRange.Usage = 0x0004
3946pp_data->cap[82]->NotRange.Reserved1 = 0x0004
3947pp_data->cap[82]->NotRange.StringIndex = 0
3948pp_data->cap[82]->NotRange.Reserved2 = 0
3949pp_data->cap[82]->NotRange.DesignatorIndex = 0
3950pp_data->cap[82]->NotRange.Reserved3 = 0
3951pp_data->cap[82]->NotRange.DataIndex = 82
3952pp_data->cap[82]->NotRange.Reserved4 = 82
3953pp_data->cap[82]->NotButton.HasNull = 0
3954pp_data->cap[82]->NotButton.Reserved4 = 0x000000
3955pp_data->cap[82]->NotButton.LogicalMin = 0
3956pp_data->cap[82]->NotButton.LogicalMax = 4095
3957pp_data->cap[82]->NotButton.PhysicalMin = 0
3958pp_data->cap[82]->NotButton.PhysicalMax = 0
3959pp_data->cap[82]->Units = 0
3960pp_data->cap[82]->UnitsExp = 0
3961
3962pp_data->cap[83]->UsagePage = 0xFF01
3963pp_data->cap[83]->ReportID = 0x02
3964pp_data->cap[83]->BitPosition = 0
3965pp_data->cap[83]->BitSize = 16
3966pp_data->cap[83]->ReportCount = 1
3967pp_data->cap[83]->BytePosition = 0x0005
3968pp_data->cap[83]->BitCount = 16
3969pp_data->cap[83]->BitField = 0x02
3970pp_data->cap[83]->NextBytePosition = 0x0007
3971pp_data->cap[83]->LinkCollection = 0x0002
3972pp_data->cap[83]->LinkUsagePage = 0xFF01
3973pp_data->cap[83]->LinkUsage = 0x0002
3974pp_data->cap[83]->IsMultipleItemsForArray = 0
3975pp_data->cap[83]->IsButtonCap = 0
3976pp_data->cap[83]->IsPadding = 0
3977pp_data->cap[83]->IsAbsolute = 1
3978pp_data->cap[83]->IsRange = 0
3979pp_data->cap[83]->IsAlias = 0
3980pp_data->cap[83]->IsStringRange = 0
3981pp_data->cap[83]->IsDesignatorRange = 0
3982pp_data->cap[83]->Reserved1 = 0x000000
3983pp_data->cap[83]->pp_cap->UnknownTokens[0].Token = 0x00
3984pp_data->cap[83]->pp_cap->UnknownTokens[0].Reserved = 0x000000
3985pp_data->cap[83]->pp_cap->UnknownTokens[0].BitField = 0x00000000
3986pp_data->cap[83]->pp_cap->UnknownTokens[1].Token = 0x00
3987pp_data->cap[83]->pp_cap->UnknownTokens[1].Reserved = 0x000000
3988pp_data->cap[83]->pp_cap->UnknownTokens[1].BitField = 0x00000000
3989pp_data->cap[83]->pp_cap->UnknownTokens[2].Token = 0x00
3990pp_data->cap[83]->pp_cap->UnknownTokens[2].Reserved = 0x000000
3991pp_data->cap[83]->pp_cap->UnknownTokens[2].BitField = 0x00000000
3992pp_data->cap[83]->pp_cap->UnknownTokens[3].Token = 0x00
3993pp_data->cap[83]->pp_cap->UnknownTokens[3].Reserved = 0x000000
3994pp_data->cap[83]->pp_cap->UnknownTokens[3].BitField = 0x00000000
3995pp_data->cap[83]->NotRange.Usage = 0x0004
3996pp_data->cap[83]->NotRange.Reserved1 = 0x0004
3997pp_data->cap[83]->NotRange.StringIndex = 0
3998pp_data->cap[83]->NotRange.Reserved2 = 0
3999pp_data->cap[83]->NotRange.DesignatorIndex = 0
4000pp_data->cap[83]->NotRange.Reserved3 = 0
4001pp_data->cap[83]->NotRange.DataIndex = 83
4002pp_data->cap[83]->NotRange.Reserved4 = 83
4003pp_data->cap[83]->NotButton.HasNull = 0
4004pp_data->cap[83]->NotButton.Reserved4 = 0x000000
4005pp_data->cap[83]->NotButton.LogicalMin = 0
4006pp_data->cap[83]->NotButton.LogicalMax = 4095
4007pp_data->cap[83]->NotButton.PhysicalMin = 0
4008pp_data->cap[83]->NotButton.PhysicalMax = 0
4009pp_data->cap[83]->Units = 0
4010pp_data->cap[83]->UnitsExp = 0
4011
4012pp_data->cap[84]->UsagePage = 0xFF01
4013pp_data->cap[84]->ReportID = 0x02
4014pp_data->cap[84]->BitPosition = 0
4015pp_data->cap[84]->BitSize = 16
4016pp_data->cap[84]->ReportCount = 1
4017pp_data->cap[84]->BytePosition = 0x0003
4018pp_data->cap[84]->BitCount = 16
4019pp_data->cap[84]->BitField = 0x02
4020pp_data->cap[84]->NextBytePosition = 0x0005
4021pp_data->cap[84]->LinkCollection = 0x0002
4022pp_data->cap[84]->LinkUsagePage = 0xFF01
4023pp_data->cap[84]->LinkUsage = 0x0002
4024pp_data->cap[84]->IsMultipleItemsForArray = 0
4025pp_data->cap[84]->IsButtonCap = 0
4026pp_data->cap[84]->IsPadding = 0
4027pp_data->cap[84]->IsAbsolute = 1
4028pp_data->cap[84]->IsRange = 0
4029pp_data->cap[84]->IsAlias = 0
4030pp_data->cap[84]->IsStringRange = 0
4031pp_data->cap[84]->IsDesignatorRange = 0
4032pp_data->cap[84]->Reserved1 = 0x000000
4033pp_data->cap[84]->pp_cap->UnknownTokens[0].Token = 0x00
4034pp_data->cap[84]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4035pp_data->cap[84]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4036pp_data->cap[84]->pp_cap->UnknownTokens[1].Token = 0x00
4037pp_data->cap[84]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4038pp_data->cap[84]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4039pp_data->cap[84]->pp_cap->UnknownTokens[2].Token = 0x00
4040pp_data->cap[84]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4041pp_data->cap[84]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4042pp_data->cap[84]->pp_cap->UnknownTokens[3].Token = 0x00
4043pp_data->cap[84]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4044pp_data->cap[84]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4045pp_data->cap[84]->NotRange.Usage = 0x0004
4046pp_data->cap[84]->NotRange.Reserved1 = 0x0004
4047pp_data->cap[84]->NotRange.StringIndex = 0
4048pp_data->cap[84]->NotRange.Reserved2 = 0
4049pp_data->cap[84]->NotRange.DesignatorIndex = 0
4050pp_data->cap[84]->NotRange.Reserved3 = 0
4051pp_data->cap[84]->NotRange.DataIndex = 84
4052pp_data->cap[84]->NotRange.Reserved4 = 84
4053pp_data->cap[84]->NotButton.HasNull = 0
4054pp_data->cap[84]->NotButton.Reserved4 = 0x000000
4055pp_data->cap[84]->NotButton.LogicalMin = 0
4056pp_data->cap[84]->NotButton.LogicalMax = 4095
4057pp_data->cap[84]->NotButton.PhysicalMin = 0
4058pp_data->cap[84]->NotButton.PhysicalMax = 0
4059pp_data->cap[84]->Units = 0
4060pp_data->cap[84]->UnitsExp = 0
4061
4062pp_data->cap[85]->UsagePage = 0xFF01
4063pp_data->cap[85]->ReportID = 0x02
4064pp_data->cap[85]->BitPosition = 0
4065pp_data->cap[85]->BitSize = 16
4066pp_data->cap[85]->ReportCount = 1
4067pp_data->cap[85]->BytePosition = 0x0001
4068pp_data->cap[85]->BitCount = 16
4069pp_data->cap[85]->BitField = 0x02
4070pp_data->cap[85]->NextBytePosition = 0x0003
4071pp_data->cap[85]->LinkCollection = 0x0002
4072pp_data->cap[85]->LinkUsagePage = 0xFF01
4073pp_data->cap[85]->LinkUsage = 0x0002
4074pp_data->cap[85]->IsMultipleItemsForArray = 0
4075pp_data->cap[85]->IsButtonCap = 0
4076pp_data->cap[85]->IsPadding = 0
4077pp_data->cap[85]->IsAbsolute = 1
4078pp_data->cap[85]->IsRange = 0
4079pp_data->cap[85]->IsAlias = 0
4080pp_data->cap[85]->IsStringRange = 0
4081pp_data->cap[85]->IsDesignatorRange = 0
4082pp_data->cap[85]->Reserved1 = 0x000000
4083pp_data->cap[85]->pp_cap->UnknownTokens[0].Token = 0x00
4084pp_data->cap[85]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4085pp_data->cap[85]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4086pp_data->cap[85]->pp_cap->UnknownTokens[1].Token = 0x00
4087pp_data->cap[85]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4088pp_data->cap[85]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4089pp_data->cap[85]->pp_cap->UnknownTokens[2].Token = 0x00
4090pp_data->cap[85]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4091pp_data->cap[85]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4092pp_data->cap[85]->pp_cap->UnknownTokens[3].Token = 0x00
4093pp_data->cap[85]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4094pp_data->cap[85]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4095pp_data->cap[85]->NotRange.Usage = 0x0004
4096pp_data->cap[85]->NotRange.Reserved1 = 0x0004
4097pp_data->cap[85]->NotRange.StringIndex = 0
4098pp_data->cap[85]->NotRange.Reserved2 = 0
4099pp_data->cap[85]->NotRange.DesignatorIndex = 0
4100pp_data->cap[85]->NotRange.Reserved3 = 0
4101pp_data->cap[85]->NotRange.DataIndex = 85
4102pp_data->cap[85]->NotRange.Reserved4 = 85
4103pp_data->cap[85]->NotButton.HasNull = 0
4104pp_data->cap[85]->NotButton.Reserved4 = 0x000000
4105pp_data->cap[85]->NotButton.LogicalMin = 0
4106pp_data->cap[85]->NotButton.LogicalMax = 4095
4107pp_data->cap[85]->NotButton.PhysicalMin = 0
4108pp_data->cap[85]->NotButton.PhysicalMax = 0
4109pp_data->cap[85]->Units = 0
4110pp_data->cap[85]->UnitsExp = 0
4111
4112# Output hid_pp_cap struct:
4113pp_data->cap[87]->UsagePage = 0xFF01
4114pp_data->cap[87]->ReportID = 0x80
4115pp_data->cap[87]->BitPosition = 0
4116pp_data->cap[87]->BitSize = 8
4117pp_data->cap[87]->ReportCount = 1
4118pp_data->cap[87]->BytePosition = 0x005E
4119pp_data->cap[87]->BitCount = 8
4120pp_data->cap[87]->BitField = 0x02
4121pp_data->cap[87]->NextBytePosition = 0x005F
4122pp_data->cap[87]->LinkCollection = 0x0003
4123pp_data->cap[87]->LinkUsagePage = 0xFF01
4124pp_data->cap[87]->LinkUsage = 0x0080
4125pp_data->cap[87]->IsMultipleItemsForArray = 0
4126pp_data->cap[87]->IsButtonCap = 0
4127pp_data->cap[87]->IsPadding = 0
4128pp_data->cap[87]->IsAbsolute = 1
4129pp_data->cap[87]->IsRange = 0
4130pp_data->cap[87]->IsAlias = 0
4131pp_data->cap[87]->IsStringRange = 0
4132pp_data->cap[87]->IsDesignatorRange = 0
4133pp_data->cap[87]->Reserved1 = 0x000000
4134pp_data->cap[87]->pp_cap->UnknownTokens[0].Token = 0x00
4135pp_data->cap[87]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4136pp_data->cap[87]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4137pp_data->cap[87]->pp_cap->UnknownTokens[1].Token = 0x00
4138pp_data->cap[87]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4139pp_data->cap[87]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4140pp_data->cap[87]->pp_cap->UnknownTokens[2].Token = 0x00
4141pp_data->cap[87]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4142pp_data->cap[87]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4143pp_data->cap[87]->pp_cap->UnknownTokens[3].Token = 0x00
4144pp_data->cap[87]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4145pp_data->cap[87]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4146pp_data->cap[87]->NotRange.Usage = 0x0081
4147pp_data->cap[87]->NotRange.Reserved1 = 0x0081
4148pp_data->cap[87]->NotRange.StringIndex = 0
4149pp_data->cap[87]->NotRange.Reserved2 = 0
4150pp_data->cap[87]->NotRange.DesignatorIndex = 0
4151pp_data->cap[87]->NotRange.Reserved3 = 0
4152pp_data->cap[87]->NotRange.DataIndex = 0
4153pp_data->cap[87]->NotRange.Reserved4 = 0
4154pp_data->cap[87]->NotButton.HasNull = 0
4155pp_data->cap[87]->NotButton.Reserved4 = 0x000000
4156pp_data->cap[87]->NotButton.LogicalMin = 0
4157pp_data->cap[87]->NotButton.LogicalMax = 127
4158pp_data->cap[87]->NotButton.PhysicalMin = 0
4159pp_data->cap[87]->NotButton.PhysicalMax = 0
4160pp_data->cap[87]->Units = 0
4161pp_data->cap[87]->UnitsExp = 0
4162
4163pp_data->cap[88]->UsagePage = 0xFF01
4164pp_data->cap[88]->ReportID = 0x80
4165pp_data->cap[88]->BitPosition = 0
4166pp_data->cap[88]->BitSize = 8
4167pp_data->cap[88]->ReportCount = 1
4168pp_data->cap[88]->BytePosition = 0x005D
4169pp_data->cap[88]->BitCount = 8
4170pp_data->cap[88]->BitField = 0x02
4171pp_data->cap[88]->NextBytePosition = 0x005E
4172pp_data->cap[88]->LinkCollection = 0x0003
4173pp_data->cap[88]->LinkUsagePage = 0xFF01
4174pp_data->cap[88]->LinkUsage = 0x0080
4175pp_data->cap[88]->IsMultipleItemsForArray = 0
4176pp_data->cap[88]->IsButtonCap = 0
4177pp_data->cap[88]->IsPadding = 0
4178pp_data->cap[88]->IsAbsolute = 1
4179pp_data->cap[88]->IsRange = 0
4180pp_data->cap[88]->IsAlias = 0
4181pp_data->cap[88]->IsStringRange = 0
4182pp_data->cap[88]->IsDesignatorRange = 0
4183pp_data->cap[88]->Reserved1 = 0x000000
4184pp_data->cap[88]->pp_cap->UnknownTokens[0].Token = 0x00
4185pp_data->cap[88]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4186pp_data->cap[88]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4187pp_data->cap[88]->pp_cap->UnknownTokens[1].Token = 0x00
4188pp_data->cap[88]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4189pp_data->cap[88]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4190pp_data->cap[88]->pp_cap->UnknownTokens[2].Token = 0x00
4191pp_data->cap[88]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4192pp_data->cap[88]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4193pp_data->cap[88]->pp_cap->UnknownTokens[3].Token = 0x00
4194pp_data->cap[88]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4195pp_data->cap[88]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4196pp_data->cap[88]->NotRange.Usage = 0x0081
4197pp_data->cap[88]->NotRange.Reserved1 = 0x0081
4198pp_data->cap[88]->NotRange.StringIndex = 0
4199pp_data->cap[88]->NotRange.Reserved2 = 0
4200pp_data->cap[88]->NotRange.DesignatorIndex = 0
4201pp_data->cap[88]->NotRange.Reserved3 = 0
4202pp_data->cap[88]->NotRange.DataIndex = 1
4203pp_data->cap[88]->NotRange.Reserved4 = 1
4204pp_data->cap[88]->NotButton.HasNull = 0
4205pp_data->cap[88]->NotButton.Reserved4 = 0x000000
4206pp_data->cap[88]->NotButton.LogicalMin = 0
4207pp_data->cap[88]->NotButton.LogicalMax = 127
4208pp_data->cap[88]->NotButton.PhysicalMin = 0
4209pp_data->cap[88]->NotButton.PhysicalMax = 0
4210pp_data->cap[88]->Units = 0
4211pp_data->cap[88]->UnitsExp = 0
4212
4213pp_data->cap[89]->UsagePage = 0xFF01
4214pp_data->cap[89]->ReportID = 0x80
4215pp_data->cap[89]->BitPosition = 0
4216pp_data->cap[89]->BitSize = 8
4217pp_data->cap[89]->ReportCount = 1
4218pp_data->cap[89]->BytePosition = 0x005C
4219pp_data->cap[89]->BitCount = 8
4220pp_data->cap[89]->BitField = 0x02
4221pp_data->cap[89]->NextBytePosition = 0x005D
4222pp_data->cap[89]->LinkCollection = 0x0003
4223pp_data->cap[89]->LinkUsagePage = 0xFF01
4224pp_data->cap[89]->LinkUsage = 0x0080
4225pp_data->cap[89]->IsMultipleItemsForArray = 0
4226pp_data->cap[89]->IsButtonCap = 0
4227pp_data->cap[89]->IsPadding = 0
4228pp_data->cap[89]->IsAbsolute = 1
4229pp_data->cap[89]->IsRange = 0
4230pp_data->cap[89]->IsAlias = 0
4231pp_data->cap[89]->IsStringRange = 0
4232pp_data->cap[89]->IsDesignatorRange = 0
4233pp_data->cap[89]->Reserved1 = 0x000000
4234pp_data->cap[89]->pp_cap->UnknownTokens[0].Token = 0x00
4235pp_data->cap[89]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4236pp_data->cap[89]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4237pp_data->cap[89]->pp_cap->UnknownTokens[1].Token = 0x00
4238pp_data->cap[89]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4239pp_data->cap[89]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4240pp_data->cap[89]->pp_cap->UnknownTokens[2].Token = 0x00
4241pp_data->cap[89]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4242pp_data->cap[89]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4243pp_data->cap[89]->pp_cap->UnknownTokens[3].Token = 0x00
4244pp_data->cap[89]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4245pp_data->cap[89]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4246pp_data->cap[89]->NotRange.Usage = 0x0081
4247pp_data->cap[89]->NotRange.Reserved1 = 0x0081
4248pp_data->cap[89]->NotRange.StringIndex = 0
4249pp_data->cap[89]->NotRange.Reserved2 = 0
4250pp_data->cap[89]->NotRange.DesignatorIndex = 0
4251pp_data->cap[89]->NotRange.Reserved3 = 0
4252pp_data->cap[89]->NotRange.DataIndex = 2
4253pp_data->cap[89]->NotRange.Reserved4 = 2
4254pp_data->cap[89]->NotButton.HasNull = 0
4255pp_data->cap[89]->NotButton.Reserved4 = 0x000000
4256pp_data->cap[89]->NotButton.LogicalMin = 0
4257pp_data->cap[89]->NotButton.LogicalMax = 127
4258pp_data->cap[89]->NotButton.PhysicalMin = 0
4259pp_data->cap[89]->NotButton.PhysicalMax = 0
4260pp_data->cap[89]->Units = 0
4261pp_data->cap[89]->UnitsExp = 0
4262
4263pp_data->cap[90]->UsagePage = 0xFF01
4264pp_data->cap[90]->ReportID = 0x80
4265pp_data->cap[90]->BitPosition = 0
4266pp_data->cap[90]->BitSize = 8
4267pp_data->cap[90]->ReportCount = 1
4268pp_data->cap[90]->BytePosition = 0x005B
4269pp_data->cap[90]->BitCount = 8
4270pp_data->cap[90]->BitField = 0x02
4271pp_data->cap[90]->NextBytePosition = 0x005C
4272pp_data->cap[90]->LinkCollection = 0x0003
4273pp_data->cap[90]->LinkUsagePage = 0xFF01
4274pp_data->cap[90]->LinkUsage = 0x0080
4275pp_data->cap[90]->IsMultipleItemsForArray = 0
4276pp_data->cap[90]->IsButtonCap = 0
4277pp_data->cap[90]->IsPadding = 0
4278pp_data->cap[90]->IsAbsolute = 1
4279pp_data->cap[90]->IsRange = 0
4280pp_data->cap[90]->IsAlias = 0
4281pp_data->cap[90]->IsStringRange = 0
4282pp_data->cap[90]->IsDesignatorRange = 0
4283pp_data->cap[90]->Reserved1 = 0x000000
4284pp_data->cap[90]->pp_cap->UnknownTokens[0].Token = 0x00
4285pp_data->cap[90]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4286pp_data->cap[90]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4287pp_data->cap[90]->pp_cap->UnknownTokens[1].Token = 0x00
4288pp_data->cap[90]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4289pp_data->cap[90]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4290pp_data->cap[90]->pp_cap->UnknownTokens[2].Token = 0x00
4291pp_data->cap[90]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4292pp_data->cap[90]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4293pp_data->cap[90]->pp_cap->UnknownTokens[3].Token = 0x00
4294pp_data->cap[90]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4295pp_data->cap[90]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4296pp_data->cap[90]->NotRange.Usage = 0x0081
4297pp_data->cap[90]->NotRange.Reserved1 = 0x0081
4298pp_data->cap[90]->NotRange.StringIndex = 0
4299pp_data->cap[90]->NotRange.Reserved2 = 0
4300pp_data->cap[90]->NotRange.DesignatorIndex = 0
4301pp_data->cap[90]->NotRange.Reserved3 = 0
4302pp_data->cap[90]->NotRange.DataIndex = 3
4303pp_data->cap[90]->NotRange.Reserved4 = 3
4304pp_data->cap[90]->NotButton.HasNull = 0
4305pp_data->cap[90]->NotButton.Reserved4 = 0x000000
4306pp_data->cap[90]->NotButton.LogicalMin = 0
4307pp_data->cap[90]->NotButton.LogicalMax = 127
4308pp_data->cap[90]->NotButton.PhysicalMin = 0
4309pp_data->cap[90]->NotButton.PhysicalMax = 0
4310pp_data->cap[90]->Units = 0
4311pp_data->cap[90]->UnitsExp = 0
4312
4313pp_data->cap[91]->UsagePage = 0xFF01
4314pp_data->cap[91]->ReportID = 0x80
4315pp_data->cap[91]->BitPosition = 0
4316pp_data->cap[91]->BitSize = 8
4317pp_data->cap[91]->ReportCount = 1
4318pp_data->cap[91]->BytePosition = 0x005A
4319pp_data->cap[91]->BitCount = 8
4320pp_data->cap[91]->BitField = 0x02
4321pp_data->cap[91]->NextBytePosition = 0x005B
4322pp_data->cap[91]->LinkCollection = 0x0003
4323pp_data->cap[91]->LinkUsagePage = 0xFF01
4324pp_data->cap[91]->LinkUsage = 0x0080
4325pp_data->cap[91]->IsMultipleItemsForArray = 0
4326pp_data->cap[91]->IsButtonCap = 0
4327pp_data->cap[91]->IsPadding = 0
4328pp_data->cap[91]->IsAbsolute = 1
4329pp_data->cap[91]->IsRange = 0
4330pp_data->cap[91]->IsAlias = 0
4331pp_data->cap[91]->IsStringRange = 0
4332pp_data->cap[91]->IsDesignatorRange = 0
4333pp_data->cap[91]->Reserved1 = 0x000000
4334pp_data->cap[91]->pp_cap->UnknownTokens[0].Token = 0x00
4335pp_data->cap[91]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4336pp_data->cap[91]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4337pp_data->cap[91]->pp_cap->UnknownTokens[1].Token = 0x00
4338pp_data->cap[91]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4339pp_data->cap[91]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4340pp_data->cap[91]->pp_cap->UnknownTokens[2].Token = 0x00
4341pp_data->cap[91]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4342pp_data->cap[91]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4343pp_data->cap[91]->pp_cap->UnknownTokens[3].Token = 0x00
4344pp_data->cap[91]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4345pp_data->cap[91]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4346pp_data->cap[91]->NotRange.Usage = 0x0081
4347pp_data->cap[91]->NotRange.Reserved1 = 0x0081
4348pp_data->cap[91]->NotRange.StringIndex = 0
4349pp_data->cap[91]->NotRange.Reserved2 = 0
4350pp_data->cap[91]->NotRange.DesignatorIndex = 0
4351pp_data->cap[91]->NotRange.Reserved3 = 0
4352pp_data->cap[91]->NotRange.DataIndex = 4
4353pp_data->cap[91]->NotRange.Reserved4 = 4
4354pp_data->cap[91]->NotButton.HasNull = 0
4355pp_data->cap[91]->NotButton.Reserved4 = 0x000000
4356pp_data->cap[91]->NotButton.LogicalMin = 0
4357pp_data->cap[91]->NotButton.LogicalMax = 127
4358pp_data->cap[91]->NotButton.PhysicalMin = 0
4359pp_data->cap[91]->NotButton.PhysicalMax = 0
4360pp_data->cap[91]->Units = 0
4361pp_data->cap[91]->UnitsExp = 0
4362
4363pp_data->cap[92]->UsagePage = 0xFF01
4364pp_data->cap[92]->ReportID = 0x80
4365pp_data->cap[92]->BitPosition = 0
4366pp_data->cap[92]->BitSize = 8
4367pp_data->cap[92]->ReportCount = 1
4368pp_data->cap[92]->BytePosition = 0x0059
4369pp_data->cap[92]->BitCount = 8
4370pp_data->cap[92]->BitField = 0x02
4371pp_data->cap[92]->NextBytePosition = 0x005A
4372pp_data->cap[92]->LinkCollection = 0x0003
4373pp_data->cap[92]->LinkUsagePage = 0xFF01
4374pp_data->cap[92]->LinkUsage = 0x0080
4375pp_data->cap[92]->IsMultipleItemsForArray = 0
4376pp_data->cap[92]->IsButtonCap = 0
4377pp_data->cap[92]->IsPadding = 0
4378pp_data->cap[92]->IsAbsolute = 1
4379pp_data->cap[92]->IsRange = 0
4380pp_data->cap[92]->IsAlias = 0
4381pp_data->cap[92]->IsStringRange = 0
4382pp_data->cap[92]->IsDesignatorRange = 0
4383pp_data->cap[92]->Reserved1 = 0x000000
4384pp_data->cap[92]->pp_cap->UnknownTokens[0].Token = 0x00
4385pp_data->cap[92]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4386pp_data->cap[92]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4387pp_data->cap[92]->pp_cap->UnknownTokens[1].Token = 0x00
4388pp_data->cap[92]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4389pp_data->cap[92]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4390pp_data->cap[92]->pp_cap->UnknownTokens[2].Token = 0x00
4391pp_data->cap[92]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4392pp_data->cap[92]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4393pp_data->cap[92]->pp_cap->UnknownTokens[3].Token = 0x00
4394pp_data->cap[92]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4395pp_data->cap[92]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4396pp_data->cap[92]->NotRange.Usage = 0x0081
4397pp_data->cap[92]->NotRange.Reserved1 = 0x0081
4398pp_data->cap[92]->NotRange.StringIndex = 0
4399pp_data->cap[92]->NotRange.Reserved2 = 0
4400pp_data->cap[92]->NotRange.DesignatorIndex = 0
4401pp_data->cap[92]->NotRange.Reserved3 = 0
4402pp_data->cap[92]->NotRange.DataIndex = 5
4403pp_data->cap[92]->NotRange.Reserved4 = 5
4404pp_data->cap[92]->NotButton.HasNull = 0
4405pp_data->cap[92]->NotButton.Reserved4 = 0x000000
4406pp_data->cap[92]->NotButton.LogicalMin = 0
4407pp_data->cap[92]->NotButton.LogicalMax = 127
4408pp_data->cap[92]->NotButton.PhysicalMin = 0
4409pp_data->cap[92]->NotButton.PhysicalMax = 0
4410pp_data->cap[92]->Units = 0
4411pp_data->cap[92]->UnitsExp = 0
4412
4413pp_data->cap[93]->UsagePage = 0xFF01
4414pp_data->cap[93]->ReportID = 0x80
4415pp_data->cap[93]->BitPosition = 0
4416pp_data->cap[93]->BitSize = 8
4417pp_data->cap[93]->ReportCount = 1
4418pp_data->cap[93]->BytePosition = 0x0058
4419pp_data->cap[93]->BitCount = 8
4420pp_data->cap[93]->BitField = 0x02
4421pp_data->cap[93]->NextBytePosition = 0x0059
4422pp_data->cap[93]->LinkCollection = 0x0003
4423pp_data->cap[93]->LinkUsagePage = 0xFF01
4424pp_data->cap[93]->LinkUsage = 0x0080
4425pp_data->cap[93]->IsMultipleItemsForArray = 0
4426pp_data->cap[93]->IsButtonCap = 0
4427pp_data->cap[93]->IsPadding = 0
4428pp_data->cap[93]->IsAbsolute = 1
4429pp_data->cap[93]->IsRange = 0
4430pp_data->cap[93]->IsAlias = 0
4431pp_data->cap[93]->IsStringRange = 0
4432pp_data->cap[93]->IsDesignatorRange = 0
4433pp_data->cap[93]->Reserved1 = 0x000000
4434pp_data->cap[93]->pp_cap->UnknownTokens[0].Token = 0x00
4435pp_data->cap[93]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4436pp_data->cap[93]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4437pp_data->cap[93]->pp_cap->UnknownTokens[1].Token = 0x00
4438pp_data->cap[93]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4439pp_data->cap[93]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4440pp_data->cap[93]->pp_cap->UnknownTokens[2].Token = 0x00
4441pp_data->cap[93]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4442pp_data->cap[93]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4443pp_data->cap[93]->pp_cap->UnknownTokens[3].Token = 0x00
4444pp_data->cap[93]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4445pp_data->cap[93]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4446pp_data->cap[93]->NotRange.Usage = 0x0081
4447pp_data->cap[93]->NotRange.Reserved1 = 0x0081
4448pp_data->cap[93]->NotRange.StringIndex = 0
4449pp_data->cap[93]->NotRange.Reserved2 = 0
4450pp_data->cap[93]->NotRange.DesignatorIndex = 0
4451pp_data->cap[93]->NotRange.Reserved3 = 0
4452pp_data->cap[93]->NotRange.DataIndex = 6
4453pp_data->cap[93]->NotRange.Reserved4 = 6
4454pp_data->cap[93]->NotButton.HasNull = 0
4455pp_data->cap[93]->NotButton.Reserved4 = 0x000000
4456pp_data->cap[93]->NotButton.LogicalMin = 0
4457pp_data->cap[93]->NotButton.LogicalMax = 127
4458pp_data->cap[93]->NotButton.PhysicalMin = 0
4459pp_data->cap[93]->NotButton.PhysicalMax = 0
4460pp_data->cap[93]->Units = 0
4461pp_data->cap[93]->UnitsExp = 0
4462
4463pp_data->cap[94]->UsagePage = 0xFF01
4464pp_data->cap[94]->ReportID = 0x80
4465pp_data->cap[94]->BitPosition = 0
4466pp_data->cap[94]->BitSize = 8
4467pp_data->cap[94]->ReportCount = 1
4468pp_data->cap[94]->BytePosition = 0x0057
4469pp_data->cap[94]->BitCount = 8
4470pp_data->cap[94]->BitField = 0x02
4471pp_data->cap[94]->NextBytePosition = 0x0058
4472pp_data->cap[94]->LinkCollection = 0x0003
4473pp_data->cap[94]->LinkUsagePage = 0xFF01
4474pp_data->cap[94]->LinkUsage = 0x0080
4475pp_data->cap[94]->IsMultipleItemsForArray = 0
4476pp_data->cap[94]->IsButtonCap = 0
4477pp_data->cap[94]->IsPadding = 0
4478pp_data->cap[94]->IsAbsolute = 1
4479pp_data->cap[94]->IsRange = 0
4480pp_data->cap[94]->IsAlias = 0
4481pp_data->cap[94]->IsStringRange = 0
4482pp_data->cap[94]->IsDesignatorRange = 0
4483pp_data->cap[94]->Reserved1 = 0x000000
4484pp_data->cap[94]->pp_cap->UnknownTokens[0].Token = 0x00
4485pp_data->cap[94]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4486pp_data->cap[94]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4487pp_data->cap[94]->pp_cap->UnknownTokens[1].Token = 0x00
4488pp_data->cap[94]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4489pp_data->cap[94]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4490pp_data->cap[94]->pp_cap->UnknownTokens[2].Token = 0x00
4491pp_data->cap[94]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4492pp_data->cap[94]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4493pp_data->cap[94]->pp_cap->UnknownTokens[3].Token = 0x00
4494pp_data->cap[94]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4495pp_data->cap[94]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4496pp_data->cap[94]->NotRange.Usage = 0x0081
4497pp_data->cap[94]->NotRange.Reserved1 = 0x0081
4498pp_data->cap[94]->NotRange.StringIndex = 0
4499pp_data->cap[94]->NotRange.Reserved2 = 0
4500pp_data->cap[94]->NotRange.DesignatorIndex = 0
4501pp_data->cap[94]->NotRange.Reserved3 = 0
4502pp_data->cap[94]->NotRange.DataIndex = 7
4503pp_data->cap[94]->NotRange.Reserved4 = 7
4504pp_data->cap[94]->NotButton.HasNull = 0
4505pp_data->cap[94]->NotButton.Reserved4 = 0x000000
4506pp_data->cap[94]->NotButton.LogicalMin = 0
4507pp_data->cap[94]->NotButton.LogicalMax = 127
4508pp_data->cap[94]->NotButton.PhysicalMin = 0
4509pp_data->cap[94]->NotButton.PhysicalMax = 0
4510pp_data->cap[94]->Units = 0
4511pp_data->cap[94]->UnitsExp = 0
4512
4513pp_data->cap[95]->UsagePage = 0xFF01
4514pp_data->cap[95]->ReportID = 0x80
4515pp_data->cap[95]->BitPosition = 0
4516pp_data->cap[95]->BitSize = 8
4517pp_data->cap[95]->ReportCount = 1
4518pp_data->cap[95]->BytePosition = 0x0056
4519pp_data->cap[95]->BitCount = 8
4520pp_data->cap[95]->BitField = 0x02
4521pp_data->cap[95]->NextBytePosition = 0x0057
4522pp_data->cap[95]->LinkCollection = 0x0003
4523pp_data->cap[95]->LinkUsagePage = 0xFF01
4524pp_data->cap[95]->LinkUsage = 0x0080
4525pp_data->cap[95]->IsMultipleItemsForArray = 0
4526pp_data->cap[95]->IsButtonCap = 0
4527pp_data->cap[95]->IsPadding = 0
4528pp_data->cap[95]->IsAbsolute = 1
4529pp_data->cap[95]->IsRange = 0
4530pp_data->cap[95]->IsAlias = 0
4531pp_data->cap[95]->IsStringRange = 0
4532pp_data->cap[95]->IsDesignatorRange = 0
4533pp_data->cap[95]->Reserved1 = 0x000000
4534pp_data->cap[95]->pp_cap->UnknownTokens[0].Token = 0x00
4535pp_data->cap[95]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4536pp_data->cap[95]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4537pp_data->cap[95]->pp_cap->UnknownTokens[1].Token = 0x00
4538pp_data->cap[95]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4539pp_data->cap[95]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4540pp_data->cap[95]->pp_cap->UnknownTokens[2].Token = 0x00
4541pp_data->cap[95]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4542pp_data->cap[95]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4543pp_data->cap[95]->pp_cap->UnknownTokens[3].Token = 0x00
4544pp_data->cap[95]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4545pp_data->cap[95]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4546pp_data->cap[95]->NotRange.Usage = 0x0081
4547pp_data->cap[95]->NotRange.Reserved1 = 0x0081
4548pp_data->cap[95]->NotRange.StringIndex = 0
4549pp_data->cap[95]->NotRange.Reserved2 = 0
4550pp_data->cap[95]->NotRange.DesignatorIndex = 0
4551pp_data->cap[95]->NotRange.Reserved3 = 0
4552pp_data->cap[95]->NotRange.DataIndex = 8
4553pp_data->cap[95]->NotRange.Reserved4 = 8
4554pp_data->cap[95]->NotButton.HasNull = 0
4555pp_data->cap[95]->NotButton.Reserved4 = 0x000000
4556pp_data->cap[95]->NotButton.LogicalMin = 0
4557pp_data->cap[95]->NotButton.LogicalMax = 127
4558pp_data->cap[95]->NotButton.PhysicalMin = 0
4559pp_data->cap[95]->NotButton.PhysicalMax = 0
4560pp_data->cap[95]->Units = 0
4561pp_data->cap[95]->UnitsExp = 0
4562
4563pp_data->cap[96]->UsagePage = 0xFF01
4564pp_data->cap[96]->ReportID = 0x80
4565pp_data->cap[96]->BitPosition = 0
4566pp_data->cap[96]->BitSize = 8
4567pp_data->cap[96]->ReportCount = 1
4568pp_data->cap[96]->BytePosition = 0x0055
4569pp_data->cap[96]->BitCount = 8
4570pp_data->cap[96]->BitField = 0x02
4571pp_data->cap[96]->NextBytePosition = 0x0056
4572pp_data->cap[96]->LinkCollection = 0x0003
4573pp_data->cap[96]->LinkUsagePage = 0xFF01
4574pp_data->cap[96]->LinkUsage = 0x0080
4575pp_data->cap[96]->IsMultipleItemsForArray = 0
4576pp_data->cap[96]->IsButtonCap = 0
4577pp_data->cap[96]->IsPadding = 0
4578pp_data->cap[96]->IsAbsolute = 1
4579pp_data->cap[96]->IsRange = 0
4580pp_data->cap[96]->IsAlias = 0
4581pp_data->cap[96]->IsStringRange = 0
4582pp_data->cap[96]->IsDesignatorRange = 0
4583pp_data->cap[96]->Reserved1 = 0x000000
4584pp_data->cap[96]->pp_cap->UnknownTokens[0].Token = 0x00
4585pp_data->cap[96]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4586pp_data->cap[96]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4587pp_data->cap[96]->pp_cap->UnknownTokens[1].Token = 0x00
4588pp_data->cap[96]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4589pp_data->cap[96]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4590pp_data->cap[96]->pp_cap->UnknownTokens[2].Token = 0x00
4591pp_data->cap[96]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4592pp_data->cap[96]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4593pp_data->cap[96]->pp_cap->UnknownTokens[3].Token = 0x00
4594pp_data->cap[96]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4595pp_data->cap[96]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4596pp_data->cap[96]->NotRange.Usage = 0x0081
4597pp_data->cap[96]->NotRange.Reserved1 = 0x0081
4598pp_data->cap[96]->NotRange.StringIndex = 0
4599pp_data->cap[96]->NotRange.Reserved2 = 0
4600pp_data->cap[96]->NotRange.DesignatorIndex = 0
4601pp_data->cap[96]->NotRange.Reserved3 = 0
4602pp_data->cap[96]->NotRange.DataIndex = 9
4603pp_data->cap[96]->NotRange.Reserved4 = 9
4604pp_data->cap[96]->NotButton.HasNull = 0
4605pp_data->cap[96]->NotButton.Reserved4 = 0x000000
4606pp_data->cap[96]->NotButton.LogicalMin = 0
4607pp_data->cap[96]->NotButton.LogicalMax = 127
4608pp_data->cap[96]->NotButton.PhysicalMin = 0
4609pp_data->cap[96]->NotButton.PhysicalMax = 0
4610pp_data->cap[96]->Units = 0
4611pp_data->cap[96]->UnitsExp = 0
4612
4613pp_data->cap[97]->UsagePage = 0xFF01
4614pp_data->cap[97]->ReportID = 0x80
4615pp_data->cap[97]->BitPosition = 0
4616pp_data->cap[97]->BitSize = 8
4617pp_data->cap[97]->ReportCount = 1
4618pp_data->cap[97]->BytePosition = 0x0054
4619pp_data->cap[97]->BitCount = 8
4620pp_data->cap[97]->BitField = 0x02
4621pp_data->cap[97]->NextBytePosition = 0x0055
4622pp_data->cap[97]->LinkCollection = 0x0003
4623pp_data->cap[97]->LinkUsagePage = 0xFF01
4624pp_data->cap[97]->LinkUsage = 0x0080
4625pp_data->cap[97]->IsMultipleItemsForArray = 0
4626pp_data->cap[97]->IsButtonCap = 0
4627pp_data->cap[97]->IsPadding = 0
4628pp_data->cap[97]->IsAbsolute = 1
4629pp_data->cap[97]->IsRange = 0
4630pp_data->cap[97]->IsAlias = 0
4631pp_data->cap[97]->IsStringRange = 0
4632pp_data->cap[97]->IsDesignatorRange = 0
4633pp_data->cap[97]->Reserved1 = 0x000000
4634pp_data->cap[97]->pp_cap->UnknownTokens[0].Token = 0x00
4635pp_data->cap[97]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4636pp_data->cap[97]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4637pp_data->cap[97]->pp_cap->UnknownTokens[1].Token = 0x00
4638pp_data->cap[97]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4639pp_data->cap[97]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4640pp_data->cap[97]->pp_cap->UnknownTokens[2].Token = 0x00
4641pp_data->cap[97]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4642pp_data->cap[97]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4643pp_data->cap[97]->pp_cap->UnknownTokens[3].Token = 0x00
4644pp_data->cap[97]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4645pp_data->cap[97]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4646pp_data->cap[97]->NotRange.Usage = 0x0081
4647pp_data->cap[97]->NotRange.Reserved1 = 0x0081
4648pp_data->cap[97]->NotRange.StringIndex = 0
4649pp_data->cap[97]->NotRange.Reserved2 = 0
4650pp_data->cap[97]->NotRange.DesignatorIndex = 0
4651pp_data->cap[97]->NotRange.Reserved3 = 0
4652pp_data->cap[97]->NotRange.DataIndex = 10
4653pp_data->cap[97]->NotRange.Reserved4 = 10
4654pp_data->cap[97]->NotButton.HasNull = 0
4655pp_data->cap[97]->NotButton.Reserved4 = 0x000000
4656pp_data->cap[97]->NotButton.LogicalMin = 0
4657pp_data->cap[97]->NotButton.LogicalMax = 127
4658pp_data->cap[97]->NotButton.PhysicalMin = 0
4659pp_data->cap[97]->NotButton.PhysicalMax = 0
4660pp_data->cap[97]->Units = 0
4661pp_data->cap[97]->UnitsExp = 0
4662
4663pp_data->cap[98]->UsagePage = 0xFF01
4664pp_data->cap[98]->ReportID = 0x80
4665pp_data->cap[98]->BitPosition = 0
4666pp_data->cap[98]->BitSize = 8
4667pp_data->cap[98]->ReportCount = 1
4668pp_data->cap[98]->BytePosition = 0x0053
4669pp_data->cap[98]->BitCount = 8
4670pp_data->cap[98]->BitField = 0x02
4671pp_data->cap[98]->NextBytePosition = 0x0054
4672pp_data->cap[98]->LinkCollection = 0x0003
4673pp_data->cap[98]->LinkUsagePage = 0xFF01
4674pp_data->cap[98]->LinkUsage = 0x0080
4675pp_data->cap[98]->IsMultipleItemsForArray = 0
4676pp_data->cap[98]->IsButtonCap = 0
4677pp_data->cap[98]->IsPadding = 0
4678pp_data->cap[98]->IsAbsolute = 1
4679pp_data->cap[98]->IsRange = 0
4680pp_data->cap[98]->IsAlias = 0
4681pp_data->cap[98]->IsStringRange = 0
4682pp_data->cap[98]->IsDesignatorRange = 0
4683pp_data->cap[98]->Reserved1 = 0x000000
4684pp_data->cap[98]->pp_cap->UnknownTokens[0].Token = 0x00
4685pp_data->cap[98]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4686pp_data->cap[98]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4687pp_data->cap[98]->pp_cap->UnknownTokens[1].Token = 0x00
4688pp_data->cap[98]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4689pp_data->cap[98]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4690pp_data->cap[98]->pp_cap->UnknownTokens[2].Token = 0x00
4691pp_data->cap[98]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4692pp_data->cap[98]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4693pp_data->cap[98]->pp_cap->UnknownTokens[3].Token = 0x00
4694pp_data->cap[98]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4695pp_data->cap[98]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4696pp_data->cap[98]->NotRange.Usage = 0x0081
4697pp_data->cap[98]->NotRange.Reserved1 = 0x0081
4698pp_data->cap[98]->NotRange.StringIndex = 0
4699pp_data->cap[98]->NotRange.Reserved2 = 0
4700pp_data->cap[98]->NotRange.DesignatorIndex = 0
4701pp_data->cap[98]->NotRange.Reserved3 = 0
4702pp_data->cap[98]->NotRange.DataIndex = 11
4703pp_data->cap[98]->NotRange.Reserved4 = 11
4704pp_data->cap[98]->NotButton.HasNull = 0
4705pp_data->cap[98]->NotButton.Reserved4 = 0x000000
4706pp_data->cap[98]->NotButton.LogicalMin = 0
4707pp_data->cap[98]->NotButton.LogicalMax = 127
4708pp_data->cap[98]->NotButton.PhysicalMin = 0
4709pp_data->cap[98]->NotButton.PhysicalMax = 0
4710pp_data->cap[98]->Units = 0
4711pp_data->cap[98]->UnitsExp = 0
4712
4713pp_data->cap[99]->UsagePage = 0xFF01
4714pp_data->cap[99]->ReportID = 0x80
4715pp_data->cap[99]->BitPosition = 0
4716pp_data->cap[99]->BitSize = 8
4717pp_data->cap[99]->ReportCount = 1
4718pp_data->cap[99]->BytePosition = 0x0052
4719pp_data->cap[99]->BitCount = 8
4720pp_data->cap[99]->BitField = 0x02
4721pp_data->cap[99]->NextBytePosition = 0x0053
4722pp_data->cap[99]->LinkCollection = 0x0003
4723pp_data->cap[99]->LinkUsagePage = 0xFF01
4724pp_data->cap[99]->LinkUsage = 0x0080
4725pp_data->cap[99]->IsMultipleItemsForArray = 0
4726pp_data->cap[99]->IsButtonCap = 0
4727pp_data->cap[99]->IsPadding = 0
4728pp_data->cap[99]->IsAbsolute = 1
4729pp_data->cap[99]->IsRange = 0
4730pp_data->cap[99]->IsAlias = 0
4731pp_data->cap[99]->IsStringRange = 0
4732pp_data->cap[99]->IsDesignatorRange = 0
4733pp_data->cap[99]->Reserved1 = 0x000000
4734pp_data->cap[99]->pp_cap->UnknownTokens[0].Token = 0x00
4735pp_data->cap[99]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4736pp_data->cap[99]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4737pp_data->cap[99]->pp_cap->UnknownTokens[1].Token = 0x00
4738pp_data->cap[99]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4739pp_data->cap[99]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4740pp_data->cap[99]->pp_cap->UnknownTokens[2].Token = 0x00
4741pp_data->cap[99]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4742pp_data->cap[99]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4743pp_data->cap[99]->pp_cap->UnknownTokens[3].Token = 0x00
4744pp_data->cap[99]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4745pp_data->cap[99]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4746pp_data->cap[99]->NotRange.Usage = 0x0081
4747pp_data->cap[99]->NotRange.Reserved1 = 0x0081
4748pp_data->cap[99]->NotRange.StringIndex = 0
4749pp_data->cap[99]->NotRange.Reserved2 = 0
4750pp_data->cap[99]->NotRange.DesignatorIndex = 0
4751pp_data->cap[99]->NotRange.Reserved3 = 0
4752pp_data->cap[99]->NotRange.DataIndex = 12
4753pp_data->cap[99]->NotRange.Reserved4 = 12
4754pp_data->cap[99]->NotButton.HasNull = 0
4755pp_data->cap[99]->NotButton.Reserved4 = 0x000000
4756pp_data->cap[99]->NotButton.LogicalMin = 0
4757pp_data->cap[99]->NotButton.LogicalMax = 127
4758pp_data->cap[99]->NotButton.PhysicalMin = 0
4759pp_data->cap[99]->NotButton.PhysicalMax = 0
4760pp_data->cap[99]->Units = 0
4761pp_data->cap[99]->UnitsExp = 0
4762
4763pp_data->cap[100]->UsagePage = 0xFF01
4764pp_data->cap[100]->ReportID = 0x80
4765pp_data->cap[100]->BitPosition = 0
4766pp_data->cap[100]->BitSize = 8
4767pp_data->cap[100]->ReportCount = 1
4768pp_data->cap[100]->BytePosition = 0x0051
4769pp_data->cap[100]->BitCount = 8
4770pp_data->cap[100]->BitField = 0x02
4771pp_data->cap[100]->NextBytePosition = 0x0052
4772pp_data->cap[100]->LinkCollection = 0x0003
4773pp_data->cap[100]->LinkUsagePage = 0xFF01
4774pp_data->cap[100]->LinkUsage = 0x0080
4775pp_data->cap[100]->IsMultipleItemsForArray = 0
4776pp_data->cap[100]->IsButtonCap = 0
4777pp_data->cap[100]->IsPadding = 0
4778pp_data->cap[100]->IsAbsolute = 1
4779pp_data->cap[100]->IsRange = 0
4780pp_data->cap[100]->IsAlias = 0
4781pp_data->cap[100]->IsStringRange = 0
4782pp_data->cap[100]->IsDesignatorRange = 0
4783pp_data->cap[100]->Reserved1 = 0x000000
4784pp_data->cap[100]->pp_cap->UnknownTokens[0].Token = 0x00
4785pp_data->cap[100]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4786pp_data->cap[100]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4787pp_data->cap[100]->pp_cap->UnknownTokens[1].Token = 0x00
4788pp_data->cap[100]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4789pp_data->cap[100]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4790pp_data->cap[100]->pp_cap->UnknownTokens[2].Token = 0x00
4791pp_data->cap[100]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4792pp_data->cap[100]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4793pp_data->cap[100]->pp_cap->UnknownTokens[3].Token = 0x00
4794pp_data->cap[100]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4795pp_data->cap[100]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4796pp_data->cap[100]->NotRange.Usage = 0x0081
4797pp_data->cap[100]->NotRange.Reserved1 = 0x0081
4798pp_data->cap[100]->NotRange.StringIndex = 0
4799pp_data->cap[100]->NotRange.Reserved2 = 0
4800pp_data->cap[100]->NotRange.DesignatorIndex = 0
4801pp_data->cap[100]->NotRange.Reserved3 = 0
4802pp_data->cap[100]->NotRange.DataIndex = 13
4803pp_data->cap[100]->NotRange.Reserved4 = 13
4804pp_data->cap[100]->NotButton.HasNull = 0
4805pp_data->cap[100]->NotButton.Reserved4 = 0x000000
4806pp_data->cap[100]->NotButton.LogicalMin = 0
4807pp_data->cap[100]->NotButton.LogicalMax = 127
4808pp_data->cap[100]->NotButton.PhysicalMin = 0
4809pp_data->cap[100]->NotButton.PhysicalMax = 0
4810pp_data->cap[100]->Units = 0
4811pp_data->cap[100]->UnitsExp = 0
4812
4813pp_data->cap[101]->UsagePage = 0xFF01
4814pp_data->cap[101]->ReportID = 0x80
4815pp_data->cap[101]->BitPosition = 0
4816pp_data->cap[101]->BitSize = 8
4817pp_data->cap[101]->ReportCount = 1
4818pp_data->cap[101]->BytePosition = 0x0050
4819pp_data->cap[101]->BitCount = 8
4820pp_data->cap[101]->BitField = 0x02
4821pp_data->cap[101]->NextBytePosition = 0x0051
4822pp_data->cap[101]->LinkCollection = 0x0003
4823pp_data->cap[101]->LinkUsagePage = 0xFF01
4824pp_data->cap[101]->LinkUsage = 0x0080
4825pp_data->cap[101]->IsMultipleItemsForArray = 0
4826pp_data->cap[101]->IsButtonCap = 0
4827pp_data->cap[101]->IsPadding = 0
4828pp_data->cap[101]->IsAbsolute = 1
4829pp_data->cap[101]->IsRange = 0
4830pp_data->cap[101]->IsAlias = 0
4831pp_data->cap[101]->IsStringRange = 0
4832pp_data->cap[101]->IsDesignatorRange = 0
4833pp_data->cap[101]->Reserved1 = 0x000000
4834pp_data->cap[101]->pp_cap->UnknownTokens[0].Token = 0x00
4835pp_data->cap[101]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4836pp_data->cap[101]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4837pp_data->cap[101]->pp_cap->UnknownTokens[1].Token = 0x00
4838pp_data->cap[101]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4839pp_data->cap[101]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4840pp_data->cap[101]->pp_cap->UnknownTokens[2].Token = 0x00
4841pp_data->cap[101]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4842pp_data->cap[101]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4843pp_data->cap[101]->pp_cap->UnknownTokens[3].Token = 0x00
4844pp_data->cap[101]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4845pp_data->cap[101]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4846pp_data->cap[101]->NotRange.Usage = 0x0081
4847pp_data->cap[101]->NotRange.Reserved1 = 0x0081
4848pp_data->cap[101]->NotRange.StringIndex = 0
4849pp_data->cap[101]->NotRange.Reserved2 = 0
4850pp_data->cap[101]->NotRange.DesignatorIndex = 0
4851pp_data->cap[101]->NotRange.Reserved3 = 0
4852pp_data->cap[101]->NotRange.DataIndex = 14
4853pp_data->cap[101]->NotRange.Reserved4 = 14
4854pp_data->cap[101]->NotButton.HasNull = 0
4855pp_data->cap[101]->NotButton.Reserved4 = 0x000000
4856pp_data->cap[101]->NotButton.LogicalMin = 0
4857pp_data->cap[101]->NotButton.LogicalMax = 127
4858pp_data->cap[101]->NotButton.PhysicalMin = 0
4859pp_data->cap[101]->NotButton.PhysicalMax = 0
4860pp_data->cap[101]->Units = 0
4861pp_data->cap[101]->UnitsExp = 0
4862
4863pp_data->cap[102]->UsagePage = 0xFF01
4864pp_data->cap[102]->ReportID = 0x80
4865pp_data->cap[102]->BitPosition = 0
4866pp_data->cap[102]->BitSize = 8
4867pp_data->cap[102]->ReportCount = 1
4868pp_data->cap[102]->BytePosition = 0x004F
4869pp_data->cap[102]->BitCount = 8
4870pp_data->cap[102]->BitField = 0x02
4871pp_data->cap[102]->NextBytePosition = 0x0050
4872pp_data->cap[102]->LinkCollection = 0x0003
4873pp_data->cap[102]->LinkUsagePage = 0xFF01
4874pp_data->cap[102]->LinkUsage = 0x0080
4875pp_data->cap[102]->IsMultipleItemsForArray = 0
4876pp_data->cap[102]->IsButtonCap = 0
4877pp_data->cap[102]->IsPadding = 0
4878pp_data->cap[102]->IsAbsolute = 1
4879pp_data->cap[102]->IsRange = 0
4880pp_data->cap[102]->IsAlias = 0
4881pp_data->cap[102]->IsStringRange = 0
4882pp_data->cap[102]->IsDesignatorRange = 0
4883pp_data->cap[102]->Reserved1 = 0x000000
4884pp_data->cap[102]->pp_cap->UnknownTokens[0].Token = 0x00
4885pp_data->cap[102]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4886pp_data->cap[102]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4887pp_data->cap[102]->pp_cap->UnknownTokens[1].Token = 0x00
4888pp_data->cap[102]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4889pp_data->cap[102]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4890pp_data->cap[102]->pp_cap->UnknownTokens[2].Token = 0x00
4891pp_data->cap[102]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4892pp_data->cap[102]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4893pp_data->cap[102]->pp_cap->UnknownTokens[3].Token = 0x00
4894pp_data->cap[102]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4895pp_data->cap[102]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4896pp_data->cap[102]->NotRange.Usage = 0x0081
4897pp_data->cap[102]->NotRange.Reserved1 = 0x0081
4898pp_data->cap[102]->NotRange.StringIndex = 0
4899pp_data->cap[102]->NotRange.Reserved2 = 0
4900pp_data->cap[102]->NotRange.DesignatorIndex = 0
4901pp_data->cap[102]->NotRange.Reserved3 = 0
4902pp_data->cap[102]->NotRange.DataIndex = 15
4903pp_data->cap[102]->NotRange.Reserved4 = 15
4904pp_data->cap[102]->NotButton.HasNull = 0
4905pp_data->cap[102]->NotButton.Reserved4 = 0x000000
4906pp_data->cap[102]->NotButton.LogicalMin = 0
4907pp_data->cap[102]->NotButton.LogicalMax = 127
4908pp_data->cap[102]->NotButton.PhysicalMin = 0
4909pp_data->cap[102]->NotButton.PhysicalMax = 0
4910pp_data->cap[102]->Units = 0
4911pp_data->cap[102]->UnitsExp = 0
4912
4913pp_data->cap[103]->UsagePage = 0xFF01
4914pp_data->cap[103]->ReportID = 0x80
4915pp_data->cap[103]->BitPosition = 0
4916pp_data->cap[103]->BitSize = 8
4917pp_data->cap[103]->ReportCount = 1
4918pp_data->cap[103]->BytePosition = 0x004E
4919pp_data->cap[103]->BitCount = 8
4920pp_data->cap[103]->BitField = 0x02
4921pp_data->cap[103]->NextBytePosition = 0x004F
4922pp_data->cap[103]->LinkCollection = 0x0003
4923pp_data->cap[103]->LinkUsagePage = 0xFF01
4924pp_data->cap[103]->LinkUsage = 0x0080
4925pp_data->cap[103]->IsMultipleItemsForArray = 0
4926pp_data->cap[103]->IsButtonCap = 0
4927pp_data->cap[103]->IsPadding = 0
4928pp_data->cap[103]->IsAbsolute = 1
4929pp_data->cap[103]->IsRange = 0
4930pp_data->cap[103]->IsAlias = 0
4931pp_data->cap[103]->IsStringRange = 0
4932pp_data->cap[103]->IsDesignatorRange = 0
4933pp_data->cap[103]->Reserved1 = 0x000000
4934pp_data->cap[103]->pp_cap->UnknownTokens[0].Token = 0x00
4935pp_data->cap[103]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4936pp_data->cap[103]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4937pp_data->cap[103]->pp_cap->UnknownTokens[1].Token = 0x00
4938pp_data->cap[103]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4939pp_data->cap[103]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4940pp_data->cap[103]->pp_cap->UnknownTokens[2].Token = 0x00
4941pp_data->cap[103]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4942pp_data->cap[103]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4943pp_data->cap[103]->pp_cap->UnknownTokens[3].Token = 0x00
4944pp_data->cap[103]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4945pp_data->cap[103]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4946pp_data->cap[103]->NotRange.Usage = 0x0081
4947pp_data->cap[103]->NotRange.Reserved1 = 0x0081
4948pp_data->cap[103]->NotRange.StringIndex = 0
4949pp_data->cap[103]->NotRange.Reserved2 = 0
4950pp_data->cap[103]->NotRange.DesignatorIndex = 0
4951pp_data->cap[103]->NotRange.Reserved3 = 0
4952pp_data->cap[103]->NotRange.DataIndex = 16
4953pp_data->cap[103]->NotRange.Reserved4 = 16
4954pp_data->cap[103]->NotButton.HasNull = 0
4955pp_data->cap[103]->NotButton.Reserved4 = 0x000000
4956pp_data->cap[103]->NotButton.LogicalMin = 0
4957pp_data->cap[103]->NotButton.LogicalMax = 127
4958pp_data->cap[103]->NotButton.PhysicalMin = 0
4959pp_data->cap[103]->NotButton.PhysicalMax = 0
4960pp_data->cap[103]->Units = 0
4961pp_data->cap[103]->UnitsExp = 0
4962
4963pp_data->cap[104]->UsagePage = 0xFF01
4964pp_data->cap[104]->ReportID = 0x80
4965pp_data->cap[104]->BitPosition = 0
4966pp_data->cap[104]->BitSize = 8
4967pp_data->cap[104]->ReportCount = 1
4968pp_data->cap[104]->BytePosition = 0x004D
4969pp_data->cap[104]->BitCount = 8
4970pp_data->cap[104]->BitField = 0x02
4971pp_data->cap[104]->NextBytePosition = 0x004E
4972pp_data->cap[104]->LinkCollection = 0x0003
4973pp_data->cap[104]->LinkUsagePage = 0xFF01
4974pp_data->cap[104]->LinkUsage = 0x0080
4975pp_data->cap[104]->IsMultipleItemsForArray = 0
4976pp_data->cap[104]->IsButtonCap = 0
4977pp_data->cap[104]->IsPadding = 0
4978pp_data->cap[104]->IsAbsolute = 1
4979pp_data->cap[104]->IsRange = 0
4980pp_data->cap[104]->IsAlias = 0
4981pp_data->cap[104]->IsStringRange = 0
4982pp_data->cap[104]->IsDesignatorRange = 0
4983pp_data->cap[104]->Reserved1 = 0x000000
4984pp_data->cap[104]->pp_cap->UnknownTokens[0].Token = 0x00
4985pp_data->cap[104]->pp_cap->UnknownTokens[0].Reserved = 0x000000
4986pp_data->cap[104]->pp_cap->UnknownTokens[0].BitField = 0x00000000
4987pp_data->cap[104]->pp_cap->UnknownTokens[1].Token = 0x00
4988pp_data->cap[104]->pp_cap->UnknownTokens[1].Reserved = 0x000000
4989pp_data->cap[104]->pp_cap->UnknownTokens[1].BitField = 0x00000000
4990pp_data->cap[104]->pp_cap->UnknownTokens[2].Token = 0x00
4991pp_data->cap[104]->pp_cap->UnknownTokens[2].Reserved = 0x000000
4992pp_data->cap[104]->pp_cap->UnknownTokens[2].BitField = 0x00000000
4993pp_data->cap[104]->pp_cap->UnknownTokens[3].Token = 0x00
4994pp_data->cap[104]->pp_cap->UnknownTokens[3].Reserved = 0x000000
4995pp_data->cap[104]->pp_cap->UnknownTokens[3].BitField = 0x00000000
4996pp_data->cap[104]->NotRange.Usage = 0x0081
4997pp_data->cap[104]->NotRange.Reserved1 = 0x0081
4998pp_data->cap[104]->NotRange.StringIndex = 0
4999pp_data->cap[104]->NotRange.Reserved2 = 0
5000pp_data->cap[104]->NotRange.DesignatorIndex = 0
5001pp_data->cap[104]->NotRange.Reserved3 = 0
5002pp_data->cap[104]->NotRange.DataIndex = 17
5003pp_data->cap[104]->NotRange.Reserved4 = 17
5004pp_data->cap[104]->NotButton.HasNull = 0
5005pp_data->cap[104]->NotButton.Reserved4 = 0x000000
5006pp_data->cap[104]->NotButton.LogicalMin = 0
5007pp_data->cap[104]->NotButton.LogicalMax = 127
5008pp_data->cap[104]->NotButton.PhysicalMin = 0
5009pp_data->cap[104]->NotButton.PhysicalMax = 0
5010pp_data->cap[104]->Units = 0
5011pp_data->cap[104]->UnitsExp = 0
5012
5013pp_data->cap[105]->UsagePage = 0xFF01
5014pp_data->cap[105]->ReportID = 0x80
5015pp_data->cap[105]->BitPosition = 0
5016pp_data->cap[105]->BitSize = 8
5017pp_data->cap[105]->ReportCount = 1
5018pp_data->cap[105]->BytePosition = 0x004C
5019pp_data->cap[105]->BitCount = 8
5020pp_data->cap[105]->BitField = 0x02
5021pp_data->cap[105]->NextBytePosition = 0x004D
5022pp_data->cap[105]->LinkCollection = 0x0003
5023pp_data->cap[105]->LinkUsagePage = 0xFF01
5024pp_data->cap[105]->LinkUsage = 0x0080
5025pp_data->cap[105]->IsMultipleItemsForArray = 0
5026pp_data->cap[105]->IsButtonCap = 0
5027pp_data->cap[105]->IsPadding = 0
5028pp_data->cap[105]->IsAbsolute = 1
5029pp_data->cap[105]->IsRange = 0
5030pp_data->cap[105]->IsAlias = 0
5031pp_data->cap[105]->IsStringRange = 0
5032pp_data->cap[105]->IsDesignatorRange = 0
5033pp_data->cap[105]->Reserved1 = 0x000000
5034pp_data->cap[105]->pp_cap->UnknownTokens[0].Token = 0x00
5035pp_data->cap[105]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5036pp_data->cap[105]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5037pp_data->cap[105]->pp_cap->UnknownTokens[1].Token = 0x00
5038pp_data->cap[105]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5039pp_data->cap[105]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5040pp_data->cap[105]->pp_cap->UnknownTokens[2].Token = 0x00
5041pp_data->cap[105]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5042pp_data->cap[105]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5043pp_data->cap[105]->pp_cap->UnknownTokens[3].Token = 0x00
5044pp_data->cap[105]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5045pp_data->cap[105]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5046pp_data->cap[105]->NotRange.Usage = 0x0081
5047pp_data->cap[105]->NotRange.Reserved1 = 0x0081
5048pp_data->cap[105]->NotRange.StringIndex = 0
5049pp_data->cap[105]->NotRange.Reserved2 = 0
5050pp_data->cap[105]->NotRange.DesignatorIndex = 0
5051pp_data->cap[105]->NotRange.Reserved3 = 0
5052pp_data->cap[105]->NotRange.DataIndex = 18
5053pp_data->cap[105]->NotRange.Reserved4 = 18
5054pp_data->cap[105]->NotButton.HasNull = 0
5055pp_data->cap[105]->NotButton.Reserved4 = 0x000000
5056pp_data->cap[105]->NotButton.LogicalMin = 0
5057pp_data->cap[105]->NotButton.LogicalMax = 127
5058pp_data->cap[105]->NotButton.PhysicalMin = 0
5059pp_data->cap[105]->NotButton.PhysicalMax = 0
5060pp_data->cap[105]->Units = 0
5061pp_data->cap[105]->UnitsExp = 0
5062
5063pp_data->cap[106]->UsagePage = 0xFF01
5064pp_data->cap[106]->ReportID = 0x80
5065pp_data->cap[106]->BitPosition = 0
5066pp_data->cap[106]->BitSize = 8
5067pp_data->cap[106]->ReportCount = 1
5068pp_data->cap[106]->BytePosition = 0x004B
5069pp_data->cap[106]->BitCount = 8
5070pp_data->cap[106]->BitField = 0x02
5071pp_data->cap[106]->NextBytePosition = 0x004C
5072pp_data->cap[106]->LinkCollection = 0x0003
5073pp_data->cap[106]->LinkUsagePage = 0xFF01
5074pp_data->cap[106]->LinkUsage = 0x0080
5075pp_data->cap[106]->IsMultipleItemsForArray = 0
5076pp_data->cap[106]->IsButtonCap = 0
5077pp_data->cap[106]->IsPadding = 0
5078pp_data->cap[106]->IsAbsolute = 1
5079pp_data->cap[106]->IsRange = 0
5080pp_data->cap[106]->IsAlias = 0
5081pp_data->cap[106]->IsStringRange = 0
5082pp_data->cap[106]->IsDesignatorRange = 0
5083pp_data->cap[106]->Reserved1 = 0x000000
5084pp_data->cap[106]->pp_cap->UnknownTokens[0].Token = 0x00
5085pp_data->cap[106]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5086pp_data->cap[106]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5087pp_data->cap[106]->pp_cap->UnknownTokens[1].Token = 0x00
5088pp_data->cap[106]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5089pp_data->cap[106]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5090pp_data->cap[106]->pp_cap->UnknownTokens[2].Token = 0x00
5091pp_data->cap[106]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5092pp_data->cap[106]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5093pp_data->cap[106]->pp_cap->UnknownTokens[3].Token = 0x00
5094pp_data->cap[106]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5095pp_data->cap[106]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5096pp_data->cap[106]->NotRange.Usage = 0x0081
5097pp_data->cap[106]->NotRange.Reserved1 = 0x0081
5098pp_data->cap[106]->NotRange.StringIndex = 0
5099pp_data->cap[106]->NotRange.Reserved2 = 0
5100pp_data->cap[106]->NotRange.DesignatorIndex = 0
5101pp_data->cap[106]->NotRange.Reserved3 = 0
5102pp_data->cap[106]->NotRange.DataIndex = 19
5103pp_data->cap[106]->NotRange.Reserved4 = 19
5104pp_data->cap[106]->NotButton.HasNull = 0
5105pp_data->cap[106]->NotButton.Reserved4 = 0x000000
5106pp_data->cap[106]->NotButton.LogicalMin = 0
5107pp_data->cap[106]->NotButton.LogicalMax = 127
5108pp_data->cap[106]->NotButton.PhysicalMin = 0
5109pp_data->cap[106]->NotButton.PhysicalMax = 0
5110pp_data->cap[106]->Units = 0
5111pp_data->cap[106]->UnitsExp = 0
5112
5113pp_data->cap[107]->UsagePage = 0xFF01
5114pp_data->cap[107]->ReportID = 0x80
5115pp_data->cap[107]->BitPosition = 0
5116pp_data->cap[107]->BitSize = 8
5117pp_data->cap[107]->ReportCount = 1
5118pp_data->cap[107]->BytePosition = 0x004A
5119pp_data->cap[107]->BitCount = 8
5120pp_data->cap[107]->BitField = 0x02
5121pp_data->cap[107]->NextBytePosition = 0x004B
5122pp_data->cap[107]->LinkCollection = 0x0003
5123pp_data->cap[107]->LinkUsagePage = 0xFF01
5124pp_data->cap[107]->LinkUsage = 0x0080
5125pp_data->cap[107]->IsMultipleItemsForArray = 0
5126pp_data->cap[107]->IsButtonCap = 0
5127pp_data->cap[107]->IsPadding = 0
5128pp_data->cap[107]->IsAbsolute = 1
5129pp_data->cap[107]->IsRange = 0
5130pp_data->cap[107]->IsAlias = 0
5131pp_data->cap[107]->IsStringRange = 0
5132pp_data->cap[107]->IsDesignatorRange = 0
5133pp_data->cap[107]->Reserved1 = 0x000000
5134pp_data->cap[107]->pp_cap->UnknownTokens[0].Token = 0x00
5135pp_data->cap[107]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5136pp_data->cap[107]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5137pp_data->cap[107]->pp_cap->UnknownTokens[1].Token = 0x00
5138pp_data->cap[107]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5139pp_data->cap[107]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5140pp_data->cap[107]->pp_cap->UnknownTokens[2].Token = 0x00
5141pp_data->cap[107]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5142pp_data->cap[107]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5143pp_data->cap[107]->pp_cap->UnknownTokens[3].Token = 0x00
5144pp_data->cap[107]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5145pp_data->cap[107]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5146pp_data->cap[107]->NotRange.Usage = 0x0081
5147pp_data->cap[107]->NotRange.Reserved1 = 0x0081
5148pp_data->cap[107]->NotRange.StringIndex = 0
5149pp_data->cap[107]->NotRange.Reserved2 = 0
5150pp_data->cap[107]->NotRange.DesignatorIndex = 0
5151pp_data->cap[107]->NotRange.Reserved3 = 0
5152pp_data->cap[107]->NotRange.DataIndex = 20
5153pp_data->cap[107]->NotRange.Reserved4 = 20
5154pp_data->cap[107]->NotButton.HasNull = 0
5155pp_data->cap[107]->NotButton.Reserved4 = 0x000000
5156pp_data->cap[107]->NotButton.LogicalMin = 0
5157pp_data->cap[107]->NotButton.LogicalMax = 127
5158pp_data->cap[107]->NotButton.PhysicalMin = 0
5159pp_data->cap[107]->NotButton.PhysicalMax = 0
5160pp_data->cap[107]->Units = 0
5161pp_data->cap[107]->UnitsExp = 0
5162
5163pp_data->cap[108]->UsagePage = 0xFF01
5164pp_data->cap[108]->ReportID = 0x80
5165pp_data->cap[108]->BitPosition = 0
5166pp_data->cap[108]->BitSize = 8
5167pp_data->cap[108]->ReportCount = 1
5168pp_data->cap[108]->BytePosition = 0x0049
5169pp_data->cap[108]->BitCount = 8
5170pp_data->cap[108]->BitField = 0x02
5171pp_data->cap[108]->NextBytePosition = 0x004A
5172pp_data->cap[108]->LinkCollection = 0x0003
5173pp_data->cap[108]->LinkUsagePage = 0xFF01
5174pp_data->cap[108]->LinkUsage = 0x0080
5175pp_data->cap[108]->IsMultipleItemsForArray = 0
5176pp_data->cap[108]->IsButtonCap = 0
5177pp_data->cap[108]->IsPadding = 0
5178pp_data->cap[108]->IsAbsolute = 1
5179pp_data->cap[108]->IsRange = 0
5180pp_data->cap[108]->IsAlias = 0
5181pp_data->cap[108]->IsStringRange = 0
5182pp_data->cap[108]->IsDesignatorRange = 0
5183pp_data->cap[108]->Reserved1 = 0x000000
5184pp_data->cap[108]->pp_cap->UnknownTokens[0].Token = 0x00
5185pp_data->cap[108]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5186pp_data->cap[108]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5187pp_data->cap[108]->pp_cap->UnknownTokens[1].Token = 0x00
5188pp_data->cap[108]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5189pp_data->cap[108]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5190pp_data->cap[108]->pp_cap->UnknownTokens[2].Token = 0x00
5191pp_data->cap[108]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5192pp_data->cap[108]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5193pp_data->cap[108]->pp_cap->UnknownTokens[3].Token = 0x00
5194pp_data->cap[108]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5195pp_data->cap[108]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5196pp_data->cap[108]->NotRange.Usage = 0x0081
5197pp_data->cap[108]->NotRange.Reserved1 = 0x0081
5198pp_data->cap[108]->NotRange.StringIndex = 0
5199pp_data->cap[108]->NotRange.Reserved2 = 0
5200pp_data->cap[108]->NotRange.DesignatorIndex = 0
5201pp_data->cap[108]->NotRange.Reserved3 = 0
5202pp_data->cap[108]->NotRange.DataIndex = 21
5203pp_data->cap[108]->NotRange.Reserved4 = 21
5204pp_data->cap[108]->NotButton.HasNull = 0
5205pp_data->cap[108]->NotButton.Reserved4 = 0x000000
5206pp_data->cap[108]->NotButton.LogicalMin = 0
5207pp_data->cap[108]->NotButton.LogicalMax = 127
5208pp_data->cap[108]->NotButton.PhysicalMin = 0
5209pp_data->cap[108]->NotButton.PhysicalMax = 0
5210pp_data->cap[108]->Units = 0
5211pp_data->cap[108]->UnitsExp = 0
5212
5213pp_data->cap[109]->UsagePage = 0xFF01
5214pp_data->cap[109]->ReportID = 0x80
5215pp_data->cap[109]->BitPosition = 0
5216pp_data->cap[109]->BitSize = 8
5217pp_data->cap[109]->ReportCount = 1
5218pp_data->cap[109]->BytePosition = 0x0048
5219pp_data->cap[109]->BitCount = 8
5220pp_data->cap[109]->BitField = 0x02
5221pp_data->cap[109]->NextBytePosition = 0x0049
5222pp_data->cap[109]->LinkCollection = 0x0003
5223pp_data->cap[109]->LinkUsagePage = 0xFF01
5224pp_data->cap[109]->LinkUsage = 0x0080
5225pp_data->cap[109]->IsMultipleItemsForArray = 0
5226pp_data->cap[109]->IsButtonCap = 0
5227pp_data->cap[109]->IsPadding = 0
5228pp_data->cap[109]->IsAbsolute = 1
5229pp_data->cap[109]->IsRange = 0
5230pp_data->cap[109]->IsAlias = 0
5231pp_data->cap[109]->IsStringRange = 0
5232pp_data->cap[109]->IsDesignatorRange = 0
5233pp_data->cap[109]->Reserved1 = 0x000000
5234pp_data->cap[109]->pp_cap->UnknownTokens[0].Token = 0x00
5235pp_data->cap[109]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5236pp_data->cap[109]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5237pp_data->cap[109]->pp_cap->UnknownTokens[1].Token = 0x00
5238pp_data->cap[109]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5239pp_data->cap[109]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5240pp_data->cap[109]->pp_cap->UnknownTokens[2].Token = 0x00
5241pp_data->cap[109]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5242pp_data->cap[109]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5243pp_data->cap[109]->pp_cap->UnknownTokens[3].Token = 0x00
5244pp_data->cap[109]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5245pp_data->cap[109]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5246pp_data->cap[109]->NotRange.Usage = 0x0081
5247pp_data->cap[109]->NotRange.Reserved1 = 0x0081
5248pp_data->cap[109]->NotRange.StringIndex = 0
5249pp_data->cap[109]->NotRange.Reserved2 = 0
5250pp_data->cap[109]->NotRange.DesignatorIndex = 0
5251pp_data->cap[109]->NotRange.Reserved3 = 0
5252pp_data->cap[109]->NotRange.DataIndex = 22
5253pp_data->cap[109]->NotRange.Reserved4 = 22
5254pp_data->cap[109]->NotButton.HasNull = 0
5255pp_data->cap[109]->NotButton.Reserved4 = 0x000000
5256pp_data->cap[109]->NotButton.LogicalMin = 0
5257pp_data->cap[109]->NotButton.LogicalMax = 127
5258pp_data->cap[109]->NotButton.PhysicalMin = 0
5259pp_data->cap[109]->NotButton.PhysicalMax = 0
5260pp_data->cap[109]->Units = 0
5261pp_data->cap[109]->UnitsExp = 0
5262
5263pp_data->cap[110]->UsagePage = 0xFF01
5264pp_data->cap[110]->ReportID = 0x80
5265pp_data->cap[110]->BitPosition = 0
5266pp_data->cap[110]->BitSize = 8
5267pp_data->cap[110]->ReportCount = 1
5268pp_data->cap[110]->BytePosition = 0x0047
5269pp_data->cap[110]->BitCount = 8
5270pp_data->cap[110]->BitField = 0x02
5271pp_data->cap[110]->NextBytePosition = 0x0048
5272pp_data->cap[110]->LinkCollection = 0x0003
5273pp_data->cap[110]->LinkUsagePage = 0xFF01
5274pp_data->cap[110]->LinkUsage = 0x0080
5275pp_data->cap[110]->IsMultipleItemsForArray = 0
5276pp_data->cap[110]->IsButtonCap = 0
5277pp_data->cap[110]->IsPadding = 0
5278pp_data->cap[110]->IsAbsolute = 1
5279pp_data->cap[110]->IsRange = 0
5280pp_data->cap[110]->IsAlias = 0
5281pp_data->cap[110]->IsStringRange = 0
5282pp_data->cap[110]->IsDesignatorRange = 0
5283pp_data->cap[110]->Reserved1 = 0x000000
5284pp_data->cap[110]->pp_cap->UnknownTokens[0].Token = 0x00
5285pp_data->cap[110]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5286pp_data->cap[110]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5287pp_data->cap[110]->pp_cap->UnknownTokens[1].Token = 0x00
5288pp_data->cap[110]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5289pp_data->cap[110]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5290pp_data->cap[110]->pp_cap->UnknownTokens[2].Token = 0x00
5291pp_data->cap[110]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5292pp_data->cap[110]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5293pp_data->cap[110]->pp_cap->UnknownTokens[3].Token = 0x00
5294pp_data->cap[110]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5295pp_data->cap[110]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5296pp_data->cap[110]->NotRange.Usage = 0x0081
5297pp_data->cap[110]->NotRange.Reserved1 = 0x0081
5298pp_data->cap[110]->NotRange.StringIndex = 0
5299pp_data->cap[110]->NotRange.Reserved2 = 0
5300pp_data->cap[110]->NotRange.DesignatorIndex = 0
5301pp_data->cap[110]->NotRange.Reserved3 = 0
5302pp_data->cap[110]->NotRange.DataIndex = 23
5303pp_data->cap[110]->NotRange.Reserved4 = 23
5304pp_data->cap[110]->NotButton.HasNull = 0
5305pp_data->cap[110]->NotButton.Reserved4 = 0x000000
5306pp_data->cap[110]->NotButton.LogicalMin = 0
5307pp_data->cap[110]->NotButton.LogicalMax = 127
5308pp_data->cap[110]->NotButton.PhysicalMin = 0
5309pp_data->cap[110]->NotButton.PhysicalMax = 0
5310pp_data->cap[110]->Units = 0
5311pp_data->cap[110]->UnitsExp = 0
5312
5313pp_data->cap[111]->UsagePage = 0xFF01
5314pp_data->cap[111]->ReportID = 0x80
5315pp_data->cap[111]->BitPosition = 0
5316pp_data->cap[111]->BitSize = 8
5317pp_data->cap[111]->ReportCount = 1
5318pp_data->cap[111]->BytePosition = 0x0046
5319pp_data->cap[111]->BitCount = 8
5320pp_data->cap[111]->BitField = 0x02
5321pp_data->cap[111]->NextBytePosition = 0x0047
5322pp_data->cap[111]->LinkCollection = 0x0003
5323pp_data->cap[111]->LinkUsagePage = 0xFF01
5324pp_data->cap[111]->LinkUsage = 0x0080
5325pp_data->cap[111]->IsMultipleItemsForArray = 0
5326pp_data->cap[111]->IsButtonCap = 0
5327pp_data->cap[111]->IsPadding = 0
5328pp_data->cap[111]->IsAbsolute = 1
5329pp_data->cap[111]->IsRange = 0
5330pp_data->cap[111]->IsAlias = 0
5331pp_data->cap[111]->IsStringRange = 0
5332pp_data->cap[111]->IsDesignatorRange = 0
5333pp_data->cap[111]->Reserved1 = 0x000000
5334pp_data->cap[111]->pp_cap->UnknownTokens[0].Token = 0x00
5335pp_data->cap[111]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5336pp_data->cap[111]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5337pp_data->cap[111]->pp_cap->UnknownTokens[1].Token = 0x00
5338pp_data->cap[111]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5339pp_data->cap[111]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5340pp_data->cap[111]->pp_cap->UnknownTokens[2].Token = 0x00
5341pp_data->cap[111]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5342pp_data->cap[111]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5343pp_data->cap[111]->pp_cap->UnknownTokens[3].Token = 0x00
5344pp_data->cap[111]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5345pp_data->cap[111]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5346pp_data->cap[111]->NotRange.Usage = 0x0081
5347pp_data->cap[111]->NotRange.Reserved1 = 0x0081
5348pp_data->cap[111]->NotRange.StringIndex = 0
5349pp_data->cap[111]->NotRange.Reserved2 = 0
5350pp_data->cap[111]->NotRange.DesignatorIndex = 0
5351pp_data->cap[111]->NotRange.Reserved3 = 0
5352pp_data->cap[111]->NotRange.DataIndex = 24
5353pp_data->cap[111]->NotRange.Reserved4 = 24
5354pp_data->cap[111]->NotButton.HasNull = 0
5355pp_data->cap[111]->NotButton.Reserved4 = 0x000000
5356pp_data->cap[111]->NotButton.LogicalMin = 0
5357pp_data->cap[111]->NotButton.LogicalMax = 127
5358pp_data->cap[111]->NotButton.PhysicalMin = 0
5359pp_data->cap[111]->NotButton.PhysicalMax = 0
5360pp_data->cap[111]->Units = 0
5361pp_data->cap[111]->UnitsExp = 0
5362
5363pp_data->cap[112]->UsagePage = 0xFF01
5364pp_data->cap[112]->ReportID = 0x80
5365pp_data->cap[112]->BitPosition = 0
5366pp_data->cap[112]->BitSize = 8
5367pp_data->cap[112]->ReportCount = 1
5368pp_data->cap[112]->BytePosition = 0x0045
5369pp_data->cap[112]->BitCount = 8
5370pp_data->cap[112]->BitField = 0x02
5371pp_data->cap[112]->NextBytePosition = 0x0046
5372pp_data->cap[112]->LinkCollection = 0x0003
5373pp_data->cap[112]->LinkUsagePage = 0xFF01
5374pp_data->cap[112]->LinkUsage = 0x0080
5375pp_data->cap[112]->IsMultipleItemsForArray = 0
5376pp_data->cap[112]->IsButtonCap = 0
5377pp_data->cap[112]->IsPadding = 0
5378pp_data->cap[112]->IsAbsolute = 1
5379pp_data->cap[112]->IsRange = 0
5380pp_data->cap[112]->IsAlias = 0
5381pp_data->cap[112]->IsStringRange = 0
5382pp_data->cap[112]->IsDesignatorRange = 0
5383pp_data->cap[112]->Reserved1 = 0x000000
5384pp_data->cap[112]->pp_cap->UnknownTokens[0].Token = 0x00
5385pp_data->cap[112]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5386pp_data->cap[112]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5387pp_data->cap[112]->pp_cap->UnknownTokens[1].Token = 0x00
5388pp_data->cap[112]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5389pp_data->cap[112]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5390pp_data->cap[112]->pp_cap->UnknownTokens[2].Token = 0x00
5391pp_data->cap[112]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5392pp_data->cap[112]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5393pp_data->cap[112]->pp_cap->UnknownTokens[3].Token = 0x00
5394pp_data->cap[112]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5395pp_data->cap[112]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5396pp_data->cap[112]->NotRange.Usage = 0x0081
5397pp_data->cap[112]->NotRange.Reserved1 = 0x0081
5398pp_data->cap[112]->NotRange.StringIndex = 0
5399pp_data->cap[112]->NotRange.Reserved2 = 0
5400pp_data->cap[112]->NotRange.DesignatorIndex = 0
5401pp_data->cap[112]->NotRange.Reserved3 = 0
5402pp_data->cap[112]->NotRange.DataIndex = 25
5403pp_data->cap[112]->NotRange.Reserved4 = 25
5404pp_data->cap[112]->NotButton.HasNull = 0
5405pp_data->cap[112]->NotButton.Reserved4 = 0x000000
5406pp_data->cap[112]->NotButton.LogicalMin = 0
5407pp_data->cap[112]->NotButton.LogicalMax = 127
5408pp_data->cap[112]->NotButton.PhysicalMin = 0
5409pp_data->cap[112]->NotButton.PhysicalMax = 0
5410pp_data->cap[112]->Units = 0
5411pp_data->cap[112]->UnitsExp = 0
5412
5413pp_data->cap[113]->UsagePage = 0xFF01
5414pp_data->cap[113]->ReportID = 0x80
5415pp_data->cap[113]->BitPosition = 0
5416pp_data->cap[113]->BitSize = 8
5417pp_data->cap[113]->ReportCount = 1
5418pp_data->cap[113]->BytePosition = 0x0044
5419pp_data->cap[113]->BitCount = 8
5420pp_data->cap[113]->BitField = 0x02
5421pp_data->cap[113]->NextBytePosition = 0x0045
5422pp_data->cap[113]->LinkCollection = 0x0003
5423pp_data->cap[113]->LinkUsagePage = 0xFF01
5424pp_data->cap[113]->LinkUsage = 0x0080
5425pp_data->cap[113]->IsMultipleItemsForArray = 0
5426pp_data->cap[113]->IsButtonCap = 0
5427pp_data->cap[113]->IsPadding = 0
5428pp_data->cap[113]->IsAbsolute = 1
5429pp_data->cap[113]->IsRange = 0
5430pp_data->cap[113]->IsAlias = 0
5431pp_data->cap[113]->IsStringRange = 0
5432pp_data->cap[113]->IsDesignatorRange = 0
5433pp_data->cap[113]->Reserved1 = 0x000000
5434pp_data->cap[113]->pp_cap->UnknownTokens[0].Token = 0x00
5435pp_data->cap[113]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5436pp_data->cap[113]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5437pp_data->cap[113]->pp_cap->UnknownTokens[1].Token = 0x00
5438pp_data->cap[113]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5439pp_data->cap[113]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5440pp_data->cap[113]->pp_cap->UnknownTokens[2].Token = 0x00
5441pp_data->cap[113]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5442pp_data->cap[113]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5443pp_data->cap[113]->pp_cap->UnknownTokens[3].Token = 0x00
5444pp_data->cap[113]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5445pp_data->cap[113]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5446pp_data->cap[113]->NotRange.Usage = 0x0081
5447pp_data->cap[113]->NotRange.Reserved1 = 0x0081
5448pp_data->cap[113]->NotRange.StringIndex = 0
5449pp_data->cap[113]->NotRange.Reserved2 = 0
5450pp_data->cap[113]->NotRange.DesignatorIndex = 0
5451pp_data->cap[113]->NotRange.Reserved3 = 0
5452pp_data->cap[113]->NotRange.DataIndex = 26
5453pp_data->cap[113]->NotRange.Reserved4 = 26
5454pp_data->cap[113]->NotButton.HasNull = 0
5455pp_data->cap[113]->NotButton.Reserved4 = 0x000000
5456pp_data->cap[113]->NotButton.LogicalMin = 0
5457pp_data->cap[113]->NotButton.LogicalMax = 127
5458pp_data->cap[113]->NotButton.PhysicalMin = 0
5459pp_data->cap[113]->NotButton.PhysicalMax = 0
5460pp_data->cap[113]->Units = 0
5461pp_data->cap[113]->UnitsExp = 0
5462
5463pp_data->cap[114]->UsagePage = 0xFF01
5464pp_data->cap[114]->ReportID = 0x80
5465pp_data->cap[114]->BitPosition = 0
5466pp_data->cap[114]->BitSize = 8
5467pp_data->cap[114]->ReportCount = 1
5468pp_data->cap[114]->BytePosition = 0x0043
5469pp_data->cap[114]->BitCount = 8
5470pp_data->cap[114]->BitField = 0x02
5471pp_data->cap[114]->NextBytePosition = 0x0044
5472pp_data->cap[114]->LinkCollection = 0x0003
5473pp_data->cap[114]->LinkUsagePage = 0xFF01
5474pp_data->cap[114]->LinkUsage = 0x0080
5475pp_data->cap[114]->IsMultipleItemsForArray = 0
5476pp_data->cap[114]->IsButtonCap = 0
5477pp_data->cap[114]->IsPadding = 0
5478pp_data->cap[114]->IsAbsolute = 1
5479pp_data->cap[114]->IsRange = 0
5480pp_data->cap[114]->IsAlias = 0
5481pp_data->cap[114]->IsStringRange = 0
5482pp_data->cap[114]->IsDesignatorRange = 0
5483pp_data->cap[114]->Reserved1 = 0x000000
5484pp_data->cap[114]->pp_cap->UnknownTokens[0].Token = 0x00
5485pp_data->cap[114]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5486pp_data->cap[114]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5487pp_data->cap[114]->pp_cap->UnknownTokens[1].Token = 0x00
5488pp_data->cap[114]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5489pp_data->cap[114]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5490pp_data->cap[114]->pp_cap->UnknownTokens[2].Token = 0x00
5491pp_data->cap[114]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5492pp_data->cap[114]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5493pp_data->cap[114]->pp_cap->UnknownTokens[3].Token = 0x00
5494pp_data->cap[114]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5495pp_data->cap[114]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5496pp_data->cap[114]->NotRange.Usage = 0x0081
5497pp_data->cap[114]->NotRange.Reserved1 = 0x0081
5498pp_data->cap[114]->NotRange.StringIndex = 0
5499pp_data->cap[114]->NotRange.Reserved2 = 0
5500pp_data->cap[114]->NotRange.DesignatorIndex = 0
5501pp_data->cap[114]->NotRange.Reserved3 = 0
5502pp_data->cap[114]->NotRange.DataIndex = 27
5503pp_data->cap[114]->NotRange.Reserved4 = 27
5504pp_data->cap[114]->NotButton.HasNull = 0
5505pp_data->cap[114]->NotButton.Reserved4 = 0x000000
5506pp_data->cap[114]->NotButton.LogicalMin = 0
5507pp_data->cap[114]->NotButton.LogicalMax = 127
5508pp_data->cap[114]->NotButton.PhysicalMin = 0
5509pp_data->cap[114]->NotButton.PhysicalMax = 0
5510pp_data->cap[114]->Units = 0
5511pp_data->cap[114]->UnitsExp = 0
5512
5513pp_data->cap[115]->UsagePage = 0xFF01
5514pp_data->cap[115]->ReportID = 0x80
5515pp_data->cap[115]->BitPosition = 0
5516pp_data->cap[115]->BitSize = 8
5517pp_data->cap[115]->ReportCount = 1
5518pp_data->cap[115]->BytePosition = 0x0042
5519pp_data->cap[115]->BitCount = 8
5520pp_data->cap[115]->BitField = 0x02
5521pp_data->cap[115]->NextBytePosition = 0x0043
5522pp_data->cap[115]->LinkCollection = 0x0003
5523pp_data->cap[115]->LinkUsagePage = 0xFF01
5524pp_data->cap[115]->LinkUsage = 0x0080
5525pp_data->cap[115]->IsMultipleItemsForArray = 0
5526pp_data->cap[115]->IsButtonCap = 0
5527pp_data->cap[115]->IsPadding = 0
5528pp_data->cap[115]->IsAbsolute = 1
5529pp_data->cap[115]->IsRange = 0
5530pp_data->cap[115]->IsAlias = 0
5531pp_data->cap[115]->IsStringRange = 0
5532pp_data->cap[115]->IsDesignatorRange = 0
5533pp_data->cap[115]->Reserved1 = 0x000000
5534pp_data->cap[115]->pp_cap->UnknownTokens[0].Token = 0x00
5535pp_data->cap[115]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5536pp_data->cap[115]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5537pp_data->cap[115]->pp_cap->UnknownTokens[1].Token = 0x00
5538pp_data->cap[115]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5539pp_data->cap[115]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5540pp_data->cap[115]->pp_cap->UnknownTokens[2].Token = 0x00
5541pp_data->cap[115]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5542pp_data->cap[115]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5543pp_data->cap[115]->pp_cap->UnknownTokens[3].Token = 0x00
5544pp_data->cap[115]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5545pp_data->cap[115]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5546pp_data->cap[115]->NotRange.Usage = 0x0081
5547pp_data->cap[115]->NotRange.Reserved1 = 0x0081
5548pp_data->cap[115]->NotRange.StringIndex = 0
5549pp_data->cap[115]->NotRange.Reserved2 = 0
5550pp_data->cap[115]->NotRange.DesignatorIndex = 0
5551pp_data->cap[115]->NotRange.Reserved3 = 0
5552pp_data->cap[115]->NotRange.DataIndex = 28
5553pp_data->cap[115]->NotRange.Reserved4 = 28
5554pp_data->cap[115]->NotButton.HasNull = 0
5555pp_data->cap[115]->NotButton.Reserved4 = 0x000000
5556pp_data->cap[115]->NotButton.LogicalMin = 0
5557pp_data->cap[115]->NotButton.LogicalMax = 127
5558pp_data->cap[115]->NotButton.PhysicalMin = 0
5559pp_data->cap[115]->NotButton.PhysicalMax = 0
5560pp_data->cap[115]->Units = 0
5561pp_data->cap[115]->UnitsExp = 0
5562
5563pp_data->cap[116]->UsagePage = 0xFF01
5564pp_data->cap[116]->ReportID = 0x80
5565pp_data->cap[116]->BitPosition = 0
5566pp_data->cap[116]->BitSize = 8
5567pp_data->cap[116]->ReportCount = 1
5568pp_data->cap[116]->BytePosition = 0x0041
5569pp_data->cap[116]->BitCount = 8
5570pp_data->cap[116]->BitField = 0x02
5571pp_data->cap[116]->NextBytePosition = 0x0042
5572pp_data->cap[116]->LinkCollection = 0x0003
5573pp_data->cap[116]->LinkUsagePage = 0xFF01
5574pp_data->cap[116]->LinkUsage = 0x0080
5575pp_data->cap[116]->IsMultipleItemsForArray = 0
5576pp_data->cap[116]->IsButtonCap = 0
5577pp_data->cap[116]->IsPadding = 0
5578pp_data->cap[116]->IsAbsolute = 1
5579pp_data->cap[116]->IsRange = 0
5580pp_data->cap[116]->IsAlias = 0
5581pp_data->cap[116]->IsStringRange = 0
5582pp_data->cap[116]->IsDesignatorRange = 0
5583pp_data->cap[116]->Reserved1 = 0x000000
5584pp_data->cap[116]->pp_cap->UnknownTokens[0].Token = 0x00
5585pp_data->cap[116]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5586pp_data->cap[116]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5587pp_data->cap[116]->pp_cap->UnknownTokens[1].Token = 0x00
5588pp_data->cap[116]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5589pp_data->cap[116]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5590pp_data->cap[116]->pp_cap->UnknownTokens[2].Token = 0x00
5591pp_data->cap[116]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5592pp_data->cap[116]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5593pp_data->cap[116]->pp_cap->UnknownTokens[3].Token = 0x00
5594pp_data->cap[116]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5595pp_data->cap[116]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5596pp_data->cap[116]->NotRange.Usage = 0x0081
5597pp_data->cap[116]->NotRange.Reserved1 = 0x0081
5598pp_data->cap[116]->NotRange.StringIndex = 0
5599pp_data->cap[116]->NotRange.Reserved2 = 0
5600pp_data->cap[116]->NotRange.DesignatorIndex = 0
5601pp_data->cap[116]->NotRange.Reserved3 = 0
5602pp_data->cap[116]->NotRange.DataIndex = 29
5603pp_data->cap[116]->NotRange.Reserved4 = 29
5604pp_data->cap[116]->NotButton.HasNull = 0
5605pp_data->cap[116]->NotButton.Reserved4 = 0x000000
5606pp_data->cap[116]->NotButton.LogicalMin = 0
5607pp_data->cap[116]->NotButton.LogicalMax = 127
5608pp_data->cap[116]->NotButton.PhysicalMin = 0
5609pp_data->cap[116]->NotButton.PhysicalMax = 0
5610pp_data->cap[116]->Units = 0
5611pp_data->cap[116]->UnitsExp = 0
5612
5613pp_data->cap[117]->UsagePage = 0xFF01
5614pp_data->cap[117]->ReportID = 0x80
5615pp_data->cap[117]->BitPosition = 0
5616pp_data->cap[117]->BitSize = 8
5617pp_data->cap[117]->ReportCount = 1
5618pp_data->cap[117]->BytePosition = 0x0040
5619pp_data->cap[117]->BitCount = 8
5620pp_data->cap[117]->BitField = 0x02
5621pp_data->cap[117]->NextBytePosition = 0x0041
5622pp_data->cap[117]->LinkCollection = 0x0003
5623pp_data->cap[117]->LinkUsagePage = 0xFF01
5624pp_data->cap[117]->LinkUsage = 0x0080
5625pp_data->cap[117]->IsMultipleItemsForArray = 0
5626pp_data->cap[117]->IsButtonCap = 0
5627pp_data->cap[117]->IsPadding = 0
5628pp_data->cap[117]->IsAbsolute = 1
5629pp_data->cap[117]->IsRange = 0
5630pp_data->cap[117]->IsAlias = 0
5631pp_data->cap[117]->IsStringRange = 0
5632pp_data->cap[117]->IsDesignatorRange = 0
5633pp_data->cap[117]->Reserved1 = 0x000000
5634pp_data->cap[117]->pp_cap->UnknownTokens[0].Token = 0x00
5635pp_data->cap[117]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5636pp_data->cap[117]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5637pp_data->cap[117]->pp_cap->UnknownTokens[1].Token = 0x00
5638pp_data->cap[117]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5639pp_data->cap[117]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5640pp_data->cap[117]->pp_cap->UnknownTokens[2].Token = 0x00
5641pp_data->cap[117]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5642pp_data->cap[117]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5643pp_data->cap[117]->pp_cap->UnknownTokens[3].Token = 0x00
5644pp_data->cap[117]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5645pp_data->cap[117]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5646pp_data->cap[117]->NotRange.Usage = 0x0081
5647pp_data->cap[117]->NotRange.Reserved1 = 0x0081
5648pp_data->cap[117]->NotRange.StringIndex = 0
5649pp_data->cap[117]->NotRange.Reserved2 = 0
5650pp_data->cap[117]->NotRange.DesignatorIndex = 0
5651pp_data->cap[117]->NotRange.Reserved3 = 0
5652pp_data->cap[117]->NotRange.DataIndex = 30
5653pp_data->cap[117]->NotRange.Reserved4 = 30
5654pp_data->cap[117]->NotButton.HasNull = 0
5655pp_data->cap[117]->NotButton.Reserved4 = 0x000000
5656pp_data->cap[117]->NotButton.LogicalMin = 0
5657pp_data->cap[117]->NotButton.LogicalMax = 127
5658pp_data->cap[117]->NotButton.PhysicalMin = 0
5659pp_data->cap[117]->NotButton.PhysicalMax = 0
5660pp_data->cap[117]->Units = 0
5661pp_data->cap[117]->UnitsExp = 0
5662
5663pp_data->cap[118]->UsagePage = 0xFF01
5664pp_data->cap[118]->ReportID = 0x80
5665pp_data->cap[118]->BitPosition = 0
5666pp_data->cap[118]->BitSize = 8
5667pp_data->cap[118]->ReportCount = 1
5668pp_data->cap[118]->BytePosition = 0x003F
5669pp_data->cap[118]->BitCount = 8
5670pp_data->cap[118]->BitField = 0x02
5671pp_data->cap[118]->NextBytePosition = 0x0040
5672pp_data->cap[118]->LinkCollection = 0x0003
5673pp_data->cap[118]->LinkUsagePage = 0xFF01
5674pp_data->cap[118]->LinkUsage = 0x0080
5675pp_data->cap[118]->IsMultipleItemsForArray = 0
5676pp_data->cap[118]->IsButtonCap = 0
5677pp_data->cap[118]->IsPadding = 0
5678pp_data->cap[118]->IsAbsolute = 1
5679pp_data->cap[118]->IsRange = 0
5680pp_data->cap[118]->IsAlias = 0
5681pp_data->cap[118]->IsStringRange = 0
5682pp_data->cap[118]->IsDesignatorRange = 0
5683pp_data->cap[118]->Reserved1 = 0x000000
5684pp_data->cap[118]->pp_cap->UnknownTokens[0].Token = 0x00
5685pp_data->cap[118]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5686pp_data->cap[118]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5687pp_data->cap[118]->pp_cap->UnknownTokens[1].Token = 0x00
5688pp_data->cap[118]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5689pp_data->cap[118]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5690pp_data->cap[118]->pp_cap->UnknownTokens[2].Token = 0x00
5691pp_data->cap[118]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5692pp_data->cap[118]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5693pp_data->cap[118]->pp_cap->UnknownTokens[3].Token = 0x00
5694pp_data->cap[118]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5695pp_data->cap[118]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5696pp_data->cap[118]->NotRange.Usage = 0x0081
5697pp_data->cap[118]->NotRange.Reserved1 = 0x0081
5698pp_data->cap[118]->NotRange.StringIndex = 0
5699pp_data->cap[118]->NotRange.Reserved2 = 0
5700pp_data->cap[118]->NotRange.DesignatorIndex = 0
5701pp_data->cap[118]->NotRange.Reserved3 = 0
5702pp_data->cap[118]->NotRange.DataIndex = 31
5703pp_data->cap[118]->NotRange.Reserved4 = 31
5704pp_data->cap[118]->NotButton.HasNull = 0
5705pp_data->cap[118]->NotButton.Reserved4 = 0x000000
5706pp_data->cap[118]->NotButton.LogicalMin = 0
5707pp_data->cap[118]->NotButton.LogicalMax = 127
5708pp_data->cap[118]->NotButton.PhysicalMin = 0
5709pp_data->cap[118]->NotButton.PhysicalMax = 0
5710pp_data->cap[118]->Units = 0
5711pp_data->cap[118]->UnitsExp = 0
5712
5713pp_data->cap[119]->UsagePage = 0xFF01
5714pp_data->cap[119]->ReportID = 0x80
5715pp_data->cap[119]->BitPosition = 0
5716pp_data->cap[119]->BitSize = 8
5717pp_data->cap[119]->ReportCount = 1
5718pp_data->cap[119]->BytePosition = 0x003E
5719pp_data->cap[119]->BitCount = 8
5720pp_data->cap[119]->BitField = 0x02
5721pp_data->cap[119]->NextBytePosition = 0x003F
5722pp_data->cap[119]->LinkCollection = 0x0003
5723pp_data->cap[119]->LinkUsagePage = 0xFF01
5724pp_data->cap[119]->LinkUsage = 0x0080
5725pp_data->cap[119]->IsMultipleItemsForArray = 0
5726pp_data->cap[119]->IsButtonCap = 0
5727pp_data->cap[119]->IsPadding = 0
5728pp_data->cap[119]->IsAbsolute = 1
5729pp_data->cap[119]->IsRange = 0
5730pp_data->cap[119]->IsAlias = 0
5731pp_data->cap[119]->IsStringRange = 0
5732pp_data->cap[119]->IsDesignatorRange = 0
5733pp_data->cap[119]->Reserved1 = 0x000000
5734pp_data->cap[119]->pp_cap->UnknownTokens[0].Token = 0x00
5735pp_data->cap[119]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5736pp_data->cap[119]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5737pp_data->cap[119]->pp_cap->UnknownTokens[1].Token = 0x00
5738pp_data->cap[119]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5739pp_data->cap[119]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5740pp_data->cap[119]->pp_cap->UnknownTokens[2].Token = 0x00
5741pp_data->cap[119]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5742pp_data->cap[119]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5743pp_data->cap[119]->pp_cap->UnknownTokens[3].Token = 0x00
5744pp_data->cap[119]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5745pp_data->cap[119]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5746pp_data->cap[119]->NotRange.Usage = 0x0081
5747pp_data->cap[119]->NotRange.Reserved1 = 0x0081
5748pp_data->cap[119]->NotRange.StringIndex = 0
5749pp_data->cap[119]->NotRange.Reserved2 = 0
5750pp_data->cap[119]->NotRange.DesignatorIndex = 0
5751pp_data->cap[119]->NotRange.Reserved3 = 0
5752pp_data->cap[119]->NotRange.DataIndex = 32
5753pp_data->cap[119]->NotRange.Reserved4 = 32
5754pp_data->cap[119]->NotButton.HasNull = 0
5755pp_data->cap[119]->NotButton.Reserved4 = 0x000000
5756pp_data->cap[119]->NotButton.LogicalMin = 0
5757pp_data->cap[119]->NotButton.LogicalMax = 127
5758pp_data->cap[119]->NotButton.PhysicalMin = 0
5759pp_data->cap[119]->NotButton.PhysicalMax = 0
5760pp_data->cap[119]->Units = 0
5761pp_data->cap[119]->UnitsExp = 0
5762
5763pp_data->cap[120]->UsagePage = 0xFF01
5764pp_data->cap[120]->ReportID = 0x80
5765pp_data->cap[120]->BitPosition = 0
5766pp_data->cap[120]->BitSize = 8
5767pp_data->cap[120]->ReportCount = 1
5768pp_data->cap[120]->BytePosition = 0x003D
5769pp_data->cap[120]->BitCount = 8
5770pp_data->cap[120]->BitField = 0x02
5771pp_data->cap[120]->NextBytePosition = 0x003E
5772pp_data->cap[120]->LinkCollection = 0x0003
5773pp_data->cap[120]->LinkUsagePage = 0xFF01
5774pp_data->cap[120]->LinkUsage = 0x0080
5775pp_data->cap[120]->IsMultipleItemsForArray = 0
5776pp_data->cap[120]->IsButtonCap = 0
5777pp_data->cap[120]->IsPadding = 0
5778pp_data->cap[120]->IsAbsolute = 1
5779pp_data->cap[120]->IsRange = 0
5780pp_data->cap[120]->IsAlias = 0
5781pp_data->cap[120]->IsStringRange = 0
5782pp_data->cap[120]->IsDesignatorRange = 0
5783pp_data->cap[120]->Reserved1 = 0x000000
5784pp_data->cap[120]->pp_cap->UnknownTokens[0].Token = 0x00
5785pp_data->cap[120]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5786pp_data->cap[120]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5787pp_data->cap[120]->pp_cap->UnknownTokens[1].Token = 0x00
5788pp_data->cap[120]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5789pp_data->cap[120]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5790pp_data->cap[120]->pp_cap->UnknownTokens[2].Token = 0x00
5791pp_data->cap[120]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5792pp_data->cap[120]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5793pp_data->cap[120]->pp_cap->UnknownTokens[3].Token = 0x00
5794pp_data->cap[120]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5795pp_data->cap[120]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5796pp_data->cap[120]->NotRange.Usage = 0x0081
5797pp_data->cap[120]->NotRange.Reserved1 = 0x0081
5798pp_data->cap[120]->NotRange.StringIndex = 0
5799pp_data->cap[120]->NotRange.Reserved2 = 0
5800pp_data->cap[120]->NotRange.DesignatorIndex = 0
5801pp_data->cap[120]->NotRange.Reserved3 = 0
5802pp_data->cap[120]->NotRange.DataIndex = 33
5803pp_data->cap[120]->NotRange.Reserved4 = 33
5804pp_data->cap[120]->NotButton.HasNull = 0
5805pp_data->cap[120]->NotButton.Reserved4 = 0x000000
5806pp_data->cap[120]->NotButton.LogicalMin = 0
5807pp_data->cap[120]->NotButton.LogicalMax = 127
5808pp_data->cap[120]->NotButton.PhysicalMin = 0
5809pp_data->cap[120]->NotButton.PhysicalMax = 0
5810pp_data->cap[120]->Units = 0
5811pp_data->cap[120]->UnitsExp = 0
5812
5813pp_data->cap[121]->UsagePage = 0xFF01
5814pp_data->cap[121]->ReportID = 0x80
5815pp_data->cap[121]->BitPosition = 0
5816pp_data->cap[121]->BitSize = 8
5817pp_data->cap[121]->ReportCount = 1
5818pp_data->cap[121]->BytePosition = 0x003C
5819pp_data->cap[121]->BitCount = 8
5820pp_data->cap[121]->BitField = 0x02
5821pp_data->cap[121]->NextBytePosition = 0x003D
5822pp_data->cap[121]->LinkCollection = 0x0003
5823pp_data->cap[121]->LinkUsagePage = 0xFF01
5824pp_data->cap[121]->LinkUsage = 0x0080
5825pp_data->cap[121]->IsMultipleItemsForArray = 0
5826pp_data->cap[121]->IsButtonCap = 0
5827pp_data->cap[121]->IsPadding = 0
5828pp_data->cap[121]->IsAbsolute = 1
5829pp_data->cap[121]->IsRange = 0
5830pp_data->cap[121]->IsAlias = 0
5831pp_data->cap[121]->IsStringRange = 0
5832pp_data->cap[121]->IsDesignatorRange = 0
5833pp_data->cap[121]->Reserved1 = 0x000000
5834pp_data->cap[121]->pp_cap->UnknownTokens[0].Token = 0x00
5835pp_data->cap[121]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5836pp_data->cap[121]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5837pp_data->cap[121]->pp_cap->UnknownTokens[1].Token = 0x00
5838pp_data->cap[121]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5839pp_data->cap[121]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5840pp_data->cap[121]->pp_cap->UnknownTokens[2].Token = 0x00
5841pp_data->cap[121]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5842pp_data->cap[121]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5843pp_data->cap[121]->pp_cap->UnknownTokens[3].Token = 0x00
5844pp_data->cap[121]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5845pp_data->cap[121]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5846pp_data->cap[121]->NotRange.Usage = 0x0081
5847pp_data->cap[121]->NotRange.Reserved1 = 0x0081
5848pp_data->cap[121]->NotRange.StringIndex = 0
5849pp_data->cap[121]->NotRange.Reserved2 = 0
5850pp_data->cap[121]->NotRange.DesignatorIndex = 0
5851pp_data->cap[121]->NotRange.Reserved3 = 0
5852pp_data->cap[121]->NotRange.DataIndex = 34
5853pp_data->cap[121]->NotRange.Reserved4 = 34
5854pp_data->cap[121]->NotButton.HasNull = 0
5855pp_data->cap[121]->NotButton.Reserved4 = 0x000000
5856pp_data->cap[121]->NotButton.LogicalMin = 0
5857pp_data->cap[121]->NotButton.LogicalMax = 127
5858pp_data->cap[121]->NotButton.PhysicalMin = 0
5859pp_data->cap[121]->NotButton.PhysicalMax = 0
5860pp_data->cap[121]->Units = 0
5861pp_data->cap[121]->UnitsExp = 0
5862
5863pp_data->cap[122]->UsagePage = 0xFF01
5864pp_data->cap[122]->ReportID = 0x80
5865pp_data->cap[122]->BitPosition = 0
5866pp_data->cap[122]->BitSize = 8
5867pp_data->cap[122]->ReportCount = 1
5868pp_data->cap[122]->BytePosition = 0x003B
5869pp_data->cap[122]->BitCount = 8
5870pp_data->cap[122]->BitField = 0x02
5871pp_data->cap[122]->NextBytePosition = 0x003C
5872pp_data->cap[122]->LinkCollection = 0x0003
5873pp_data->cap[122]->LinkUsagePage = 0xFF01
5874pp_data->cap[122]->LinkUsage = 0x0080
5875pp_data->cap[122]->IsMultipleItemsForArray = 0
5876pp_data->cap[122]->IsButtonCap = 0
5877pp_data->cap[122]->IsPadding = 0
5878pp_data->cap[122]->IsAbsolute = 1
5879pp_data->cap[122]->IsRange = 0
5880pp_data->cap[122]->IsAlias = 0
5881pp_data->cap[122]->IsStringRange = 0
5882pp_data->cap[122]->IsDesignatorRange = 0
5883pp_data->cap[122]->Reserved1 = 0x000000
5884pp_data->cap[122]->pp_cap->UnknownTokens[0].Token = 0x00
5885pp_data->cap[122]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5886pp_data->cap[122]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5887pp_data->cap[122]->pp_cap->UnknownTokens[1].Token = 0x00
5888pp_data->cap[122]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5889pp_data->cap[122]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5890pp_data->cap[122]->pp_cap->UnknownTokens[2].Token = 0x00
5891pp_data->cap[122]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5892pp_data->cap[122]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5893pp_data->cap[122]->pp_cap->UnknownTokens[3].Token = 0x00
5894pp_data->cap[122]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5895pp_data->cap[122]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5896pp_data->cap[122]->NotRange.Usage = 0x0081
5897pp_data->cap[122]->NotRange.Reserved1 = 0x0081
5898pp_data->cap[122]->NotRange.StringIndex = 0
5899pp_data->cap[122]->NotRange.Reserved2 = 0
5900pp_data->cap[122]->NotRange.DesignatorIndex = 0
5901pp_data->cap[122]->NotRange.Reserved3 = 0
5902pp_data->cap[122]->NotRange.DataIndex = 35
5903pp_data->cap[122]->NotRange.Reserved4 = 35
5904pp_data->cap[122]->NotButton.HasNull = 0
5905pp_data->cap[122]->NotButton.Reserved4 = 0x000000
5906pp_data->cap[122]->NotButton.LogicalMin = 0
5907pp_data->cap[122]->NotButton.LogicalMax = 127
5908pp_data->cap[122]->NotButton.PhysicalMin = 0
5909pp_data->cap[122]->NotButton.PhysicalMax = 0
5910pp_data->cap[122]->Units = 0
5911pp_data->cap[122]->UnitsExp = 0
5912
5913pp_data->cap[123]->UsagePage = 0xFF01
5914pp_data->cap[123]->ReportID = 0x80
5915pp_data->cap[123]->BitPosition = 0
5916pp_data->cap[123]->BitSize = 8
5917pp_data->cap[123]->ReportCount = 1
5918pp_data->cap[123]->BytePosition = 0x003A
5919pp_data->cap[123]->BitCount = 8
5920pp_data->cap[123]->BitField = 0x02
5921pp_data->cap[123]->NextBytePosition = 0x003B
5922pp_data->cap[123]->LinkCollection = 0x0003
5923pp_data->cap[123]->LinkUsagePage = 0xFF01
5924pp_data->cap[123]->LinkUsage = 0x0080
5925pp_data->cap[123]->IsMultipleItemsForArray = 0
5926pp_data->cap[123]->IsButtonCap = 0
5927pp_data->cap[123]->IsPadding = 0
5928pp_data->cap[123]->IsAbsolute = 1
5929pp_data->cap[123]->IsRange = 0
5930pp_data->cap[123]->IsAlias = 0
5931pp_data->cap[123]->IsStringRange = 0
5932pp_data->cap[123]->IsDesignatorRange = 0
5933pp_data->cap[123]->Reserved1 = 0x000000
5934pp_data->cap[123]->pp_cap->UnknownTokens[0].Token = 0x00
5935pp_data->cap[123]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5936pp_data->cap[123]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5937pp_data->cap[123]->pp_cap->UnknownTokens[1].Token = 0x00
5938pp_data->cap[123]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5939pp_data->cap[123]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5940pp_data->cap[123]->pp_cap->UnknownTokens[2].Token = 0x00
5941pp_data->cap[123]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5942pp_data->cap[123]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5943pp_data->cap[123]->pp_cap->UnknownTokens[3].Token = 0x00
5944pp_data->cap[123]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5945pp_data->cap[123]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5946pp_data->cap[123]->NotRange.Usage = 0x0081
5947pp_data->cap[123]->NotRange.Reserved1 = 0x0081
5948pp_data->cap[123]->NotRange.StringIndex = 0
5949pp_data->cap[123]->NotRange.Reserved2 = 0
5950pp_data->cap[123]->NotRange.DesignatorIndex = 0
5951pp_data->cap[123]->NotRange.Reserved3 = 0
5952pp_data->cap[123]->NotRange.DataIndex = 36
5953pp_data->cap[123]->NotRange.Reserved4 = 36
5954pp_data->cap[123]->NotButton.HasNull = 0
5955pp_data->cap[123]->NotButton.Reserved4 = 0x000000
5956pp_data->cap[123]->NotButton.LogicalMin = 0
5957pp_data->cap[123]->NotButton.LogicalMax = 127
5958pp_data->cap[123]->NotButton.PhysicalMin = 0
5959pp_data->cap[123]->NotButton.PhysicalMax = 0
5960pp_data->cap[123]->Units = 0
5961pp_data->cap[123]->UnitsExp = 0
5962
5963pp_data->cap[124]->UsagePage = 0xFF01
5964pp_data->cap[124]->ReportID = 0x80
5965pp_data->cap[124]->BitPosition = 0
5966pp_data->cap[124]->BitSize = 8
5967pp_data->cap[124]->ReportCount = 1
5968pp_data->cap[124]->BytePosition = 0x0039
5969pp_data->cap[124]->BitCount = 8
5970pp_data->cap[124]->BitField = 0x02
5971pp_data->cap[124]->NextBytePosition = 0x003A
5972pp_data->cap[124]->LinkCollection = 0x0003
5973pp_data->cap[124]->LinkUsagePage = 0xFF01
5974pp_data->cap[124]->LinkUsage = 0x0080
5975pp_data->cap[124]->IsMultipleItemsForArray = 0
5976pp_data->cap[124]->IsButtonCap = 0
5977pp_data->cap[124]->IsPadding = 0
5978pp_data->cap[124]->IsAbsolute = 1
5979pp_data->cap[124]->IsRange = 0
5980pp_data->cap[124]->IsAlias = 0
5981pp_data->cap[124]->IsStringRange = 0
5982pp_data->cap[124]->IsDesignatorRange = 0
5983pp_data->cap[124]->Reserved1 = 0x000000
5984pp_data->cap[124]->pp_cap->UnknownTokens[0].Token = 0x00
5985pp_data->cap[124]->pp_cap->UnknownTokens[0].Reserved = 0x000000
5986pp_data->cap[124]->pp_cap->UnknownTokens[0].BitField = 0x00000000
5987pp_data->cap[124]->pp_cap->UnknownTokens[1].Token = 0x00
5988pp_data->cap[124]->pp_cap->UnknownTokens[1].Reserved = 0x000000
5989pp_data->cap[124]->pp_cap->UnknownTokens[1].BitField = 0x00000000
5990pp_data->cap[124]->pp_cap->UnknownTokens[2].Token = 0x00
5991pp_data->cap[124]->pp_cap->UnknownTokens[2].Reserved = 0x000000
5992pp_data->cap[124]->pp_cap->UnknownTokens[2].BitField = 0x00000000
5993pp_data->cap[124]->pp_cap->UnknownTokens[3].Token = 0x00
5994pp_data->cap[124]->pp_cap->UnknownTokens[3].Reserved = 0x000000
5995pp_data->cap[124]->pp_cap->UnknownTokens[3].BitField = 0x00000000
5996pp_data->cap[124]->NotRange.Usage = 0x0081
5997pp_data->cap[124]->NotRange.Reserved1 = 0x0081
5998pp_data->cap[124]->NotRange.StringIndex = 0
5999pp_data->cap[124]->NotRange.Reserved2 = 0
6000pp_data->cap[124]->NotRange.DesignatorIndex = 0
6001pp_data->cap[124]->NotRange.Reserved3 = 0
6002pp_data->cap[124]->NotRange.DataIndex = 37
6003pp_data->cap[124]->NotRange.Reserved4 = 37
6004pp_data->cap[124]->NotButton.HasNull = 0
6005pp_data->cap[124]->NotButton.Reserved4 = 0x000000
6006pp_data->cap[124]->NotButton.LogicalMin = 0
6007pp_data->cap[124]->NotButton.LogicalMax = 127
6008pp_data->cap[124]->NotButton.PhysicalMin = 0
6009pp_data->cap[124]->NotButton.PhysicalMax = 0
6010pp_data->cap[124]->Units = 0
6011pp_data->cap[124]->UnitsExp = 0
6012
6013pp_data->cap[125]->UsagePage = 0xFF01
6014pp_data->cap[125]->ReportID = 0x80
6015pp_data->cap[125]->BitPosition = 0
6016pp_data->cap[125]->BitSize = 8
6017pp_data->cap[125]->ReportCount = 1
6018pp_data->cap[125]->BytePosition = 0x0038
6019pp_data->cap[125]->BitCount = 8
6020pp_data->cap[125]->BitField = 0x02
6021pp_data->cap[125]->NextBytePosition = 0x0039
6022pp_data->cap[125]->LinkCollection = 0x0003
6023pp_data->cap[125]->LinkUsagePage = 0xFF01
6024pp_data->cap[125]->LinkUsage = 0x0080
6025pp_data->cap[125]->IsMultipleItemsForArray = 0
6026pp_data->cap[125]->IsButtonCap = 0
6027pp_data->cap[125]->IsPadding = 0
6028pp_data->cap[125]->IsAbsolute = 1
6029pp_data->cap[125]->IsRange = 0
6030pp_data->cap[125]->IsAlias = 0
6031pp_data->cap[125]->IsStringRange = 0
6032pp_data->cap[125]->IsDesignatorRange = 0
6033pp_data->cap[125]->Reserved1 = 0x000000
6034pp_data->cap[125]->pp_cap->UnknownTokens[0].Token = 0x00
6035pp_data->cap[125]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6036pp_data->cap[125]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6037pp_data->cap[125]->pp_cap->UnknownTokens[1].Token = 0x00
6038pp_data->cap[125]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6039pp_data->cap[125]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6040pp_data->cap[125]->pp_cap->UnknownTokens[2].Token = 0x00
6041pp_data->cap[125]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6042pp_data->cap[125]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6043pp_data->cap[125]->pp_cap->UnknownTokens[3].Token = 0x00
6044pp_data->cap[125]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6045pp_data->cap[125]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6046pp_data->cap[125]->NotRange.Usage = 0x0081
6047pp_data->cap[125]->NotRange.Reserved1 = 0x0081
6048pp_data->cap[125]->NotRange.StringIndex = 0
6049pp_data->cap[125]->NotRange.Reserved2 = 0
6050pp_data->cap[125]->NotRange.DesignatorIndex = 0
6051pp_data->cap[125]->NotRange.Reserved3 = 0
6052pp_data->cap[125]->NotRange.DataIndex = 38
6053pp_data->cap[125]->NotRange.Reserved4 = 38
6054pp_data->cap[125]->NotButton.HasNull = 0
6055pp_data->cap[125]->NotButton.Reserved4 = 0x000000
6056pp_data->cap[125]->NotButton.LogicalMin = 0
6057pp_data->cap[125]->NotButton.LogicalMax = 127
6058pp_data->cap[125]->NotButton.PhysicalMin = 0
6059pp_data->cap[125]->NotButton.PhysicalMax = 0
6060pp_data->cap[125]->Units = 0
6061pp_data->cap[125]->UnitsExp = 0
6062
6063pp_data->cap[126]->UsagePage = 0xFF01
6064pp_data->cap[126]->ReportID = 0x80
6065pp_data->cap[126]->BitPosition = 0
6066pp_data->cap[126]->BitSize = 8
6067pp_data->cap[126]->ReportCount = 1
6068pp_data->cap[126]->BytePosition = 0x0037
6069pp_data->cap[126]->BitCount = 8
6070pp_data->cap[126]->BitField = 0x02
6071pp_data->cap[126]->NextBytePosition = 0x0038
6072pp_data->cap[126]->LinkCollection = 0x0003
6073pp_data->cap[126]->LinkUsagePage = 0xFF01
6074pp_data->cap[126]->LinkUsage = 0x0080
6075pp_data->cap[126]->IsMultipleItemsForArray = 0
6076pp_data->cap[126]->IsButtonCap = 0
6077pp_data->cap[126]->IsPadding = 0
6078pp_data->cap[126]->IsAbsolute = 1
6079pp_data->cap[126]->IsRange = 0
6080pp_data->cap[126]->IsAlias = 0
6081pp_data->cap[126]->IsStringRange = 0
6082pp_data->cap[126]->IsDesignatorRange = 0
6083pp_data->cap[126]->Reserved1 = 0x000000
6084pp_data->cap[126]->pp_cap->UnknownTokens[0].Token = 0x00
6085pp_data->cap[126]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6086pp_data->cap[126]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6087pp_data->cap[126]->pp_cap->UnknownTokens[1].Token = 0x00
6088pp_data->cap[126]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6089pp_data->cap[126]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6090pp_data->cap[126]->pp_cap->UnknownTokens[2].Token = 0x00
6091pp_data->cap[126]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6092pp_data->cap[126]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6093pp_data->cap[126]->pp_cap->UnknownTokens[3].Token = 0x00
6094pp_data->cap[126]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6095pp_data->cap[126]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6096pp_data->cap[126]->NotRange.Usage = 0x0081
6097pp_data->cap[126]->NotRange.Reserved1 = 0x0081
6098pp_data->cap[126]->NotRange.StringIndex = 0
6099pp_data->cap[126]->NotRange.Reserved2 = 0
6100pp_data->cap[126]->NotRange.DesignatorIndex = 0
6101pp_data->cap[126]->NotRange.Reserved3 = 0
6102pp_data->cap[126]->NotRange.DataIndex = 39
6103pp_data->cap[126]->NotRange.Reserved4 = 39
6104pp_data->cap[126]->NotButton.HasNull = 0
6105pp_data->cap[126]->NotButton.Reserved4 = 0x000000
6106pp_data->cap[126]->NotButton.LogicalMin = 0
6107pp_data->cap[126]->NotButton.LogicalMax = 127
6108pp_data->cap[126]->NotButton.PhysicalMin = 0
6109pp_data->cap[126]->NotButton.PhysicalMax = 0
6110pp_data->cap[126]->Units = 0
6111pp_data->cap[126]->UnitsExp = 0
6112
6113pp_data->cap[127]->UsagePage = 0xFF01
6114pp_data->cap[127]->ReportID = 0x80
6115pp_data->cap[127]->BitPosition = 0
6116pp_data->cap[127]->BitSize = 8
6117pp_data->cap[127]->ReportCount = 1
6118pp_data->cap[127]->BytePosition = 0x0036
6119pp_data->cap[127]->BitCount = 8
6120pp_data->cap[127]->BitField = 0x02
6121pp_data->cap[127]->NextBytePosition = 0x0037
6122pp_data->cap[127]->LinkCollection = 0x0003
6123pp_data->cap[127]->LinkUsagePage = 0xFF01
6124pp_data->cap[127]->LinkUsage = 0x0080
6125pp_data->cap[127]->IsMultipleItemsForArray = 0
6126pp_data->cap[127]->IsButtonCap = 0
6127pp_data->cap[127]->IsPadding = 0
6128pp_data->cap[127]->IsAbsolute = 1
6129pp_data->cap[127]->IsRange = 0
6130pp_data->cap[127]->IsAlias = 0
6131pp_data->cap[127]->IsStringRange = 0
6132pp_data->cap[127]->IsDesignatorRange = 0
6133pp_data->cap[127]->Reserved1 = 0x000000
6134pp_data->cap[127]->pp_cap->UnknownTokens[0].Token = 0x00
6135pp_data->cap[127]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6136pp_data->cap[127]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6137pp_data->cap[127]->pp_cap->UnknownTokens[1].Token = 0x00
6138pp_data->cap[127]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6139pp_data->cap[127]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6140pp_data->cap[127]->pp_cap->UnknownTokens[2].Token = 0x00
6141pp_data->cap[127]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6142pp_data->cap[127]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6143pp_data->cap[127]->pp_cap->UnknownTokens[3].Token = 0x00
6144pp_data->cap[127]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6145pp_data->cap[127]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6146pp_data->cap[127]->NotRange.Usage = 0x0081
6147pp_data->cap[127]->NotRange.Reserved1 = 0x0081
6148pp_data->cap[127]->NotRange.StringIndex = 0
6149pp_data->cap[127]->NotRange.Reserved2 = 0
6150pp_data->cap[127]->NotRange.DesignatorIndex = 0
6151pp_data->cap[127]->NotRange.Reserved3 = 0
6152pp_data->cap[127]->NotRange.DataIndex = 40
6153pp_data->cap[127]->NotRange.Reserved4 = 40
6154pp_data->cap[127]->NotButton.HasNull = 0
6155pp_data->cap[127]->NotButton.Reserved4 = 0x000000
6156pp_data->cap[127]->NotButton.LogicalMin = 0
6157pp_data->cap[127]->NotButton.LogicalMax = 127
6158pp_data->cap[127]->NotButton.PhysicalMin = 0
6159pp_data->cap[127]->NotButton.PhysicalMax = 0
6160pp_data->cap[127]->Units = 0
6161pp_data->cap[127]->UnitsExp = 0
6162
6163pp_data->cap[128]->UsagePage = 0xFF01
6164pp_data->cap[128]->ReportID = 0x80
6165pp_data->cap[128]->BitPosition = 0
6166pp_data->cap[128]->BitSize = 8
6167pp_data->cap[128]->ReportCount = 1
6168pp_data->cap[128]->BytePosition = 0x0035
6169pp_data->cap[128]->BitCount = 8
6170pp_data->cap[128]->BitField = 0x02
6171pp_data->cap[128]->NextBytePosition = 0x0036
6172pp_data->cap[128]->LinkCollection = 0x0003
6173pp_data->cap[128]->LinkUsagePage = 0xFF01
6174pp_data->cap[128]->LinkUsage = 0x0080
6175pp_data->cap[128]->IsMultipleItemsForArray = 0
6176pp_data->cap[128]->IsButtonCap = 0
6177pp_data->cap[128]->IsPadding = 0
6178pp_data->cap[128]->IsAbsolute = 1
6179pp_data->cap[128]->IsRange = 0
6180pp_data->cap[128]->IsAlias = 0
6181pp_data->cap[128]->IsStringRange = 0
6182pp_data->cap[128]->IsDesignatorRange = 0
6183pp_data->cap[128]->Reserved1 = 0x000000
6184pp_data->cap[128]->pp_cap->UnknownTokens[0].Token = 0x00
6185pp_data->cap[128]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6186pp_data->cap[128]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6187pp_data->cap[128]->pp_cap->UnknownTokens[1].Token = 0x00
6188pp_data->cap[128]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6189pp_data->cap[128]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6190pp_data->cap[128]->pp_cap->UnknownTokens[2].Token = 0x00
6191pp_data->cap[128]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6192pp_data->cap[128]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6193pp_data->cap[128]->pp_cap->UnknownTokens[3].Token = 0x00
6194pp_data->cap[128]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6195pp_data->cap[128]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6196pp_data->cap[128]->NotRange.Usage = 0x0081
6197pp_data->cap[128]->NotRange.Reserved1 = 0x0081
6198pp_data->cap[128]->NotRange.StringIndex = 0
6199pp_data->cap[128]->NotRange.Reserved2 = 0
6200pp_data->cap[128]->NotRange.DesignatorIndex = 0
6201pp_data->cap[128]->NotRange.Reserved3 = 0
6202pp_data->cap[128]->NotRange.DataIndex = 41
6203pp_data->cap[128]->NotRange.Reserved4 = 41
6204pp_data->cap[128]->NotButton.HasNull = 0
6205pp_data->cap[128]->NotButton.Reserved4 = 0x000000
6206pp_data->cap[128]->NotButton.LogicalMin = 0
6207pp_data->cap[128]->NotButton.LogicalMax = 127
6208pp_data->cap[128]->NotButton.PhysicalMin = 0
6209pp_data->cap[128]->NotButton.PhysicalMax = 0
6210pp_data->cap[128]->Units = 0
6211pp_data->cap[128]->UnitsExp = 0
6212
6213pp_data->cap[129]->UsagePage = 0xFF01
6214pp_data->cap[129]->ReportID = 0x80
6215pp_data->cap[129]->BitPosition = 0
6216pp_data->cap[129]->BitSize = 8
6217pp_data->cap[129]->ReportCount = 1
6218pp_data->cap[129]->BytePosition = 0x0034
6219pp_data->cap[129]->BitCount = 8
6220pp_data->cap[129]->BitField = 0x02
6221pp_data->cap[129]->NextBytePosition = 0x0035
6222pp_data->cap[129]->LinkCollection = 0x0003
6223pp_data->cap[129]->LinkUsagePage = 0xFF01
6224pp_data->cap[129]->LinkUsage = 0x0080
6225pp_data->cap[129]->IsMultipleItemsForArray = 0
6226pp_data->cap[129]->IsButtonCap = 0
6227pp_data->cap[129]->IsPadding = 0
6228pp_data->cap[129]->IsAbsolute = 1
6229pp_data->cap[129]->IsRange = 0
6230pp_data->cap[129]->IsAlias = 0
6231pp_data->cap[129]->IsStringRange = 0
6232pp_data->cap[129]->IsDesignatorRange = 0
6233pp_data->cap[129]->Reserved1 = 0x000000
6234pp_data->cap[129]->pp_cap->UnknownTokens[0].Token = 0x00
6235pp_data->cap[129]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6236pp_data->cap[129]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6237pp_data->cap[129]->pp_cap->UnknownTokens[1].Token = 0x00
6238pp_data->cap[129]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6239pp_data->cap[129]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6240pp_data->cap[129]->pp_cap->UnknownTokens[2].Token = 0x00
6241pp_data->cap[129]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6242pp_data->cap[129]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6243pp_data->cap[129]->pp_cap->UnknownTokens[3].Token = 0x00
6244pp_data->cap[129]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6245pp_data->cap[129]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6246pp_data->cap[129]->NotRange.Usage = 0x0081
6247pp_data->cap[129]->NotRange.Reserved1 = 0x0081
6248pp_data->cap[129]->NotRange.StringIndex = 0
6249pp_data->cap[129]->NotRange.Reserved2 = 0
6250pp_data->cap[129]->NotRange.DesignatorIndex = 0
6251pp_data->cap[129]->NotRange.Reserved3 = 0
6252pp_data->cap[129]->NotRange.DataIndex = 42
6253pp_data->cap[129]->NotRange.Reserved4 = 42
6254pp_data->cap[129]->NotButton.HasNull = 0
6255pp_data->cap[129]->NotButton.Reserved4 = 0x000000
6256pp_data->cap[129]->NotButton.LogicalMin = 0
6257pp_data->cap[129]->NotButton.LogicalMax = 127
6258pp_data->cap[129]->NotButton.PhysicalMin = 0
6259pp_data->cap[129]->NotButton.PhysicalMax = 0
6260pp_data->cap[129]->Units = 0
6261pp_data->cap[129]->UnitsExp = 0
6262
6263pp_data->cap[130]->UsagePage = 0xFF01
6264pp_data->cap[130]->ReportID = 0x80
6265pp_data->cap[130]->BitPosition = 0
6266pp_data->cap[130]->BitSize = 8
6267pp_data->cap[130]->ReportCount = 1
6268pp_data->cap[130]->BytePosition = 0x0033
6269pp_data->cap[130]->BitCount = 8
6270pp_data->cap[130]->BitField = 0x02
6271pp_data->cap[130]->NextBytePosition = 0x0034
6272pp_data->cap[130]->LinkCollection = 0x0003
6273pp_data->cap[130]->LinkUsagePage = 0xFF01
6274pp_data->cap[130]->LinkUsage = 0x0080
6275pp_data->cap[130]->IsMultipleItemsForArray = 0
6276pp_data->cap[130]->IsButtonCap = 0
6277pp_data->cap[130]->IsPadding = 0
6278pp_data->cap[130]->IsAbsolute = 1
6279pp_data->cap[130]->IsRange = 0
6280pp_data->cap[130]->IsAlias = 0
6281pp_data->cap[130]->IsStringRange = 0
6282pp_data->cap[130]->IsDesignatorRange = 0
6283pp_data->cap[130]->Reserved1 = 0x000000
6284pp_data->cap[130]->pp_cap->UnknownTokens[0].Token = 0x00
6285pp_data->cap[130]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6286pp_data->cap[130]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6287pp_data->cap[130]->pp_cap->UnknownTokens[1].Token = 0x00
6288pp_data->cap[130]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6289pp_data->cap[130]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6290pp_data->cap[130]->pp_cap->UnknownTokens[2].Token = 0x00
6291pp_data->cap[130]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6292pp_data->cap[130]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6293pp_data->cap[130]->pp_cap->UnknownTokens[3].Token = 0x00
6294pp_data->cap[130]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6295pp_data->cap[130]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6296pp_data->cap[130]->NotRange.Usage = 0x0081
6297pp_data->cap[130]->NotRange.Reserved1 = 0x0081
6298pp_data->cap[130]->NotRange.StringIndex = 0
6299pp_data->cap[130]->NotRange.Reserved2 = 0
6300pp_data->cap[130]->NotRange.DesignatorIndex = 0
6301pp_data->cap[130]->NotRange.Reserved3 = 0
6302pp_data->cap[130]->NotRange.DataIndex = 43
6303pp_data->cap[130]->NotRange.Reserved4 = 43
6304pp_data->cap[130]->NotButton.HasNull = 0
6305pp_data->cap[130]->NotButton.Reserved4 = 0x000000
6306pp_data->cap[130]->NotButton.LogicalMin = 0
6307pp_data->cap[130]->NotButton.LogicalMax = 127
6308pp_data->cap[130]->NotButton.PhysicalMin = 0
6309pp_data->cap[130]->NotButton.PhysicalMax = 0
6310pp_data->cap[130]->Units = 0
6311pp_data->cap[130]->UnitsExp = 0
6312
6313pp_data->cap[131]->UsagePage = 0xFF01
6314pp_data->cap[131]->ReportID = 0x80
6315pp_data->cap[131]->BitPosition = 0
6316pp_data->cap[131]->BitSize = 8
6317pp_data->cap[131]->ReportCount = 1
6318pp_data->cap[131]->BytePosition = 0x0032
6319pp_data->cap[131]->BitCount = 8
6320pp_data->cap[131]->BitField = 0x02
6321pp_data->cap[131]->NextBytePosition = 0x0033
6322pp_data->cap[131]->LinkCollection = 0x0003
6323pp_data->cap[131]->LinkUsagePage = 0xFF01
6324pp_data->cap[131]->LinkUsage = 0x0080
6325pp_data->cap[131]->IsMultipleItemsForArray = 0
6326pp_data->cap[131]->IsButtonCap = 0
6327pp_data->cap[131]->IsPadding = 0
6328pp_data->cap[131]->IsAbsolute = 1
6329pp_data->cap[131]->IsRange = 0
6330pp_data->cap[131]->IsAlias = 0
6331pp_data->cap[131]->IsStringRange = 0
6332pp_data->cap[131]->IsDesignatorRange = 0
6333pp_data->cap[131]->Reserved1 = 0x000000
6334pp_data->cap[131]->pp_cap->UnknownTokens[0].Token = 0x00
6335pp_data->cap[131]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6336pp_data->cap[131]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6337pp_data->cap[131]->pp_cap->UnknownTokens[1].Token = 0x00
6338pp_data->cap[131]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6339pp_data->cap[131]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6340pp_data->cap[131]->pp_cap->UnknownTokens[2].Token = 0x00
6341pp_data->cap[131]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6342pp_data->cap[131]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6343pp_data->cap[131]->pp_cap->UnknownTokens[3].Token = 0x00
6344pp_data->cap[131]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6345pp_data->cap[131]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6346pp_data->cap[131]->NotRange.Usage = 0x0081
6347pp_data->cap[131]->NotRange.Reserved1 = 0x0081
6348pp_data->cap[131]->NotRange.StringIndex = 0
6349pp_data->cap[131]->NotRange.Reserved2 = 0
6350pp_data->cap[131]->NotRange.DesignatorIndex = 0
6351pp_data->cap[131]->NotRange.Reserved3 = 0
6352pp_data->cap[131]->NotRange.DataIndex = 44
6353pp_data->cap[131]->NotRange.Reserved4 = 44
6354pp_data->cap[131]->NotButton.HasNull = 0
6355pp_data->cap[131]->NotButton.Reserved4 = 0x000000
6356pp_data->cap[131]->NotButton.LogicalMin = 0
6357pp_data->cap[131]->NotButton.LogicalMax = 127
6358pp_data->cap[131]->NotButton.PhysicalMin = 0
6359pp_data->cap[131]->NotButton.PhysicalMax = 0
6360pp_data->cap[131]->Units = 0
6361pp_data->cap[131]->UnitsExp = 0
6362
6363pp_data->cap[132]->UsagePage = 0xFF01
6364pp_data->cap[132]->ReportID = 0x80
6365pp_data->cap[132]->BitPosition = 0
6366pp_data->cap[132]->BitSize = 8
6367pp_data->cap[132]->ReportCount = 1
6368pp_data->cap[132]->BytePosition = 0x0031
6369pp_data->cap[132]->BitCount = 8
6370pp_data->cap[132]->BitField = 0x02
6371pp_data->cap[132]->NextBytePosition = 0x0032
6372pp_data->cap[132]->LinkCollection = 0x0003
6373pp_data->cap[132]->LinkUsagePage = 0xFF01
6374pp_data->cap[132]->LinkUsage = 0x0080
6375pp_data->cap[132]->IsMultipleItemsForArray = 0
6376pp_data->cap[132]->IsButtonCap = 0
6377pp_data->cap[132]->IsPadding = 0
6378pp_data->cap[132]->IsAbsolute = 1
6379pp_data->cap[132]->IsRange = 0
6380pp_data->cap[132]->IsAlias = 0
6381pp_data->cap[132]->IsStringRange = 0
6382pp_data->cap[132]->IsDesignatorRange = 0
6383pp_data->cap[132]->Reserved1 = 0x000000
6384pp_data->cap[132]->pp_cap->UnknownTokens[0].Token = 0x00
6385pp_data->cap[132]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6386pp_data->cap[132]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6387pp_data->cap[132]->pp_cap->UnknownTokens[1].Token = 0x00
6388pp_data->cap[132]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6389pp_data->cap[132]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6390pp_data->cap[132]->pp_cap->UnknownTokens[2].Token = 0x00
6391pp_data->cap[132]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6392pp_data->cap[132]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6393pp_data->cap[132]->pp_cap->UnknownTokens[3].Token = 0x00
6394pp_data->cap[132]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6395pp_data->cap[132]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6396pp_data->cap[132]->NotRange.Usage = 0x0081
6397pp_data->cap[132]->NotRange.Reserved1 = 0x0081
6398pp_data->cap[132]->NotRange.StringIndex = 0
6399pp_data->cap[132]->NotRange.Reserved2 = 0
6400pp_data->cap[132]->NotRange.DesignatorIndex = 0
6401pp_data->cap[132]->NotRange.Reserved3 = 0
6402pp_data->cap[132]->NotRange.DataIndex = 45
6403pp_data->cap[132]->NotRange.Reserved4 = 45
6404pp_data->cap[132]->NotButton.HasNull = 0
6405pp_data->cap[132]->NotButton.Reserved4 = 0x000000
6406pp_data->cap[132]->NotButton.LogicalMin = 0
6407pp_data->cap[132]->NotButton.LogicalMax = 127
6408pp_data->cap[132]->NotButton.PhysicalMin = 0
6409pp_data->cap[132]->NotButton.PhysicalMax = 0
6410pp_data->cap[132]->Units = 0
6411pp_data->cap[132]->UnitsExp = 0
6412
6413pp_data->cap[133]->UsagePage = 0xFF01
6414pp_data->cap[133]->ReportID = 0x80
6415pp_data->cap[133]->BitPosition = 0
6416pp_data->cap[133]->BitSize = 8
6417pp_data->cap[133]->ReportCount = 1
6418pp_data->cap[133]->BytePosition = 0x0030
6419pp_data->cap[133]->BitCount = 8
6420pp_data->cap[133]->BitField = 0x02
6421pp_data->cap[133]->NextBytePosition = 0x0031
6422pp_data->cap[133]->LinkCollection = 0x0003
6423pp_data->cap[133]->LinkUsagePage = 0xFF01
6424pp_data->cap[133]->LinkUsage = 0x0080
6425pp_data->cap[133]->IsMultipleItemsForArray = 0
6426pp_data->cap[133]->IsButtonCap = 0
6427pp_data->cap[133]->IsPadding = 0
6428pp_data->cap[133]->IsAbsolute = 1
6429pp_data->cap[133]->IsRange = 0
6430pp_data->cap[133]->IsAlias = 0
6431pp_data->cap[133]->IsStringRange = 0
6432pp_data->cap[133]->IsDesignatorRange = 0
6433pp_data->cap[133]->Reserved1 = 0x000000
6434pp_data->cap[133]->pp_cap->UnknownTokens[0].Token = 0x00
6435pp_data->cap[133]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6436pp_data->cap[133]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6437pp_data->cap[133]->pp_cap->UnknownTokens[1].Token = 0x00
6438pp_data->cap[133]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6439pp_data->cap[133]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6440pp_data->cap[133]->pp_cap->UnknownTokens[2].Token = 0x00
6441pp_data->cap[133]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6442pp_data->cap[133]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6443pp_data->cap[133]->pp_cap->UnknownTokens[3].Token = 0x00
6444pp_data->cap[133]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6445pp_data->cap[133]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6446pp_data->cap[133]->NotRange.Usage = 0x0081
6447pp_data->cap[133]->NotRange.Reserved1 = 0x0081
6448pp_data->cap[133]->NotRange.StringIndex = 0
6449pp_data->cap[133]->NotRange.Reserved2 = 0
6450pp_data->cap[133]->NotRange.DesignatorIndex = 0
6451pp_data->cap[133]->NotRange.Reserved3 = 0
6452pp_data->cap[133]->NotRange.DataIndex = 46
6453pp_data->cap[133]->NotRange.Reserved4 = 46
6454pp_data->cap[133]->NotButton.HasNull = 0
6455pp_data->cap[133]->NotButton.Reserved4 = 0x000000
6456pp_data->cap[133]->NotButton.LogicalMin = 0
6457pp_data->cap[133]->NotButton.LogicalMax = 127
6458pp_data->cap[133]->NotButton.PhysicalMin = 0
6459pp_data->cap[133]->NotButton.PhysicalMax = 0
6460pp_data->cap[133]->Units = 0
6461pp_data->cap[133]->UnitsExp = 0
6462
6463pp_data->cap[134]->UsagePage = 0xFF01
6464pp_data->cap[134]->ReportID = 0x80
6465pp_data->cap[134]->BitPosition = 0
6466pp_data->cap[134]->BitSize = 8
6467pp_data->cap[134]->ReportCount = 1
6468pp_data->cap[134]->BytePosition = 0x002F
6469pp_data->cap[134]->BitCount = 8
6470pp_data->cap[134]->BitField = 0x02
6471pp_data->cap[134]->NextBytePosition = 0x0030
6472pp_data->cap[134]->LinkCollection = 0x0003
6473pp_data->cap[134]->LinkUsagePage = 0xFF01
6474pp_data->cap[134]->LinkUsage = 0x0080
6475pp_data->cap[134]->IsMultipleItemsForArray = 0
6476pp_data->cap[134]->IsButtonCap = 0
6477pp_data->cap[134]->IsPadding = 0
6478pp_data->cap[134]->IsAbsolute = 1
6479pp_data->cap[134]->IsRange = 0
6480pp_data->cap[134]->IsAlias = 0
6481pp_data->cap[134]->IsStringRange = 0
6482pp_data->cap[134]->IsDesignatorRange = 0
6483pp_data->cap[134]->Reserved1 = 0x000000
6484pp_data->cap[134]->pp_cap->UnknownTokens[0].Token = 0x00
6485pp_data->cap[134]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6486pp_data->cap[134]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6487pp_data->cap[134]->pp_cap->UnknownTokens[1].Token = 0x00
6488pp_data->cap[134]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6489pp_data->cap[134]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6490pp_data->cap[134]->pp_cap->UnknownTokens[2].Token = 0x00
6491pp_data->cap[134]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6492pp_data->cap[134]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6493pp_data->cap[134]->pp_cap->UnknownTokens[3].Token = 0x00
6494pp_data->cap[134]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6495pp_data->cap[134]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6496pp_data->cap[134]->NotRange.Usage = 0x0081
6497pp_data->cap[134]->NotRange.Reserved1 = 0x0081
6498pp_data->cap[134]->NotRange.StringIndex = 0
6499pp_data->cap[134]->NotRange.Reserved2 = 0
6500pp_data->cap[134]->NotRange.DesignatorIndex = 0
6501pp_data->cap[134]->NotRange.Reserved3 = 0
6502pp_data->cap[134]->NotRange.DataIndex = 47
6503pp_data->cap[134]->NotRange.Reserved4 = 47
6504pp_data->cap[134]->NotButton.HasNull = 0
6505pp_data->cap[134]->NotButton.Reserved4 = 0x000000
6506pp_data->cap[134]->NotButton.LogicalMin = 0
6507pp_data->cap[134]->NotButton.LogicalMax = 127
6508pp_data->cap[134]->NotButton.PhysicalMin = 0
6509pp_data->cap[134]->NotButton.PhysicalMax = 0
6510pp_data->cap[134]->Units = 0
6511pp_data->cap[134]->UnitsExp = 0
6512
6513pp_data->cap[135]->UsagePage = 0xFF01
6514pp_data->cap[135]->ReportID = 0x80
6515pp_data->cap[135]->BitPosition = 0
6516pp_data->cap[135]->BitSize = 8
6517pp_data->cap[135]->ReportCount = 1
6518pp_data->cap[135]->BytePosition = 0x002E
6519pp_data->cap[135]->BitCount = 8
6520pp_data->cap[135]->BitField = 0x02
6521pp_data->cap[135]->NextBytePosition = 0x002F
6522pp_data->cap[135]->LinkCollection = 0x0003
6523pp_data->cap[135]->LinkUsagePage = 0xFF01
6524pp_data->cap[135]->LinkUsage = 0x0080
6525pp_data->cap[135]->IsMultipleItemsForArray = 0
6526pp_data->cap[135]->IsButtonCap = 0
6527pp_data->cap[135]->IsPadding = 0
6528pp_data->cap[135]->IsAbsolute = 1
6529pp_data->cap[135]->IsRange = 0
6530pp_data->cap[135]->IsAlias = 0
6531pp_data->cap[135]->IsStringRange = 0
6532pp_data->cap[135]->IsDesignatorRange = 0
6533pp_data->cap[135]->Reserved1 = 0x000000
6534pp_data->cap[135]->pp_cap->UnknownTokens[0].Token = 0x00
6535pp_data->cap[135]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6536pp_data->cap[135]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6537pp_data->cap[135]->pp_cap->UnknownTokens[1].Token = 0x00
6538pp_data->cap[135]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6539pp_data->cap[135]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6540pp_data->cap[135]->pp_cap->UnknownTokens[2].Token = 0x00
6541pp_data->cap[135]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6542pp_data->cap[135]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6543pp_data->cap[135]->pp_cap->UnknownTokens[3].Token = 0x00
6544pp_data->cap[135]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6545pp_data->cap[135]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6546pp_data->cap[135]->NotRange.Usage = 0x0081
6547pp_data->cap[135]->NotRange.Reserved1 = 0x0081
6548pp_data->cap[135]->NotRange.StringIndex = 0
6549pp_data->cap[135]->NotRange.Reserved2 = 0
6550pp_data->cap[135]->NotRange.DesignatorIndex = 0
6551pp_data->cap[135]->NotRange.Reserved3 = 0
6552pp_data->cap[135]->NotRange.DataIndex = 48
6553pp_data->cap[135]->NotRange.Reserved4 = 48
6554pp_data->cap[135]->NotButton.HasNull = 0
6555pp_data->cap[135]->NotButton.Reserved4 = 0x000000
6556pp_data->cap[135]->NotButton.LogicalMin = 0
6557pp_data->cap[135]->NotButton.LogicalMax = 127
6558pp_data->cap[135]->NotButton.PhysicalMin = 0
6559pp_data->cap[135]->NotButton.PhysicalMax = 0
6560pp_data->cap[135]->Units = 0
6561pp_data->cap[135]->UnitsExp = 0
6562
6563pp_data->cap[136]->UsagePage = 0xFF01
6564pp_data->cap[136]->ReportID = 0x80
6565pp_data->cap[136]->BitPosition = 0
6566pp_data->cap[136]->BitSize = 8
6567pp_data->cap[136]->ReportCount = 1
6568pp_data->cap[136]->BytePosition = 0x002D
6569pp_data->cap[136]->BitCount = 8
6570pp_data->cap[136]->BitField = 0x02
6571pp_data->cap[136]->NextBytePosition = 0x002E
6572pp_data->cap[136]->LinkCollection = 0x0003
6573pp_data->cap[136]->LinkUsagePage = 0xFF01
6574pp_data->cap[136]->LinkUsage = 0x0080
6575pp_data->cap[136]->IsMultipleItemsForArray = 0
6576pp_data->cap[136]->IsButtonCap = 0
6577pp_data->cap[136]->IsPadding = 0
6578pp_data->cap[136]->IsAbsolute = 1
6579pp_data->cap[136]->IsRange = 0
6580pp_data->cap[136]->IsAlias = 0
6581pp_data->cap[136]->IsStringRange = 0
6582pp_data->cap[136]->IsDesignatorRange = 0
6583pp_data->cap[136]->Reserved1 = 0x000000
6584pp_data->cap[136]->pp_cap->UnknownTokens[0].Token = 0x00
6585pp_data->cap[136]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6586pp_data->cap[136]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6587pp_data->cap[136]->pp_cap->UnknownTokens[1].Token = 0x00
6588pp_data->cap[136]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6589pp_data->cap[136]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6590pp_data->cap[136]->pp_cap->UnknownTokens[2].Token = 0x00
6591pp_data->cap[136]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6592pp_data->cap[136]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6593pp_data->cap[136]->pp_cap->UnknownTokens[3].Token = 0x00
6594pp_data->cap[136]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6595pp_data->cap[136]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6596pp_data->cap[136]->NotRange.Usage = 0x0081
6597pp_data->cap[136]->NotRange.Reserved1 = 0x0081
6598pp_data->cap[136]->NotRange.StringIndex = 0
6599pp_data->cap[136]->NotRange.Reserved2 = 0
6600pp_data->cap[136]->NotRange.DesignatorIndex = 0
6601pp_data->cap[136]->NotRange.Reserved3 = 0
6602pp_data->cap[136]->NotRange.DataIndex = 49
6603pp_data->cap[136]->NotRange.Reserved4 = 49
6604pp_data->cap[136]->NotButton.HasNull = 0
6605pp_data->cap[136]->NotButton.Reserved4 = 0x000000
6606pp_data->cap[136]->NotButton.LogicalMin = 0
6607pp_data->cap[136]->NotButton.LogicalMax = 127
6608pp_data->cap[136]->NotButton.PhysicalMin = 0
6609pp_data->cap[136]->NotButton.PhysicalMax = 0
6610pp_data->cap[136]->Units = 0
6611pp_data->cap[136]->UnitsExp = 0
6612
6613pp_data->cap[137]->UsagePage = 0xFF01
6614pp_data->cap[137]->ReportID = 0x80
6615pp_data->cap[137]->BitPosition = 0
6616pp_data->cap[137]->BitSize = 8
6617pp_data->cap[137]->ReportCount = 1
6618pp_data->cap[137]->BytePosition = 0x002C
6619pp_data->cap[137]->BitCount = 8
6620pp_data->cap[137]->BitField = 0x02
6621pp_data->cap[137]->NextBytePosition = 0x002D
6622pp_data->cap[137]->LinkCollection = 0x0003
6623pp_data->cap[137]->LinkUsagePage = 0xFF01
6624pp_data->cap[137]->LinkUsage = 0x0080
6625pp_data->cap[137]->IsMultipleItemsForArray = 0
6626pp_data->cap[137]->IsButtonCap = 0
6627pp_data->cap[137]->IsPadding = 0
6628pp_data->cap[137]->IsAbsolute = 1
6629pp_data->cap[137]->IsRange = 0
6630pp_data->cap[137]->IsAlias = 0
6631pp_data->cap[137]->IsStringRange = 0
6632pp_data->cap[137]->IsDesignatorRange = 0
6633pp_data->cap[137]->Reserved1 = 0x000000
6634pp_data->cap[137]->pp_cap->UnknownTokens[0].Token = 0x00
6635pp_data->cap[137]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6636pp_data->cap[137]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6637pp_data->cap[137]->pp_cap->UnknownTokens[1].Token = 0x00
6638pp_data->cap[137]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6639pp_data->cap[137]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6640pp_data->cap[137]->pp_cap->UnknownTokens[2].Token = 0x00
6641pp_data->cap[137]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6642pp_data->cap[137]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6643pp_data->cap[137]->pp_cap->UnknownTokens[3].Token = 0x00
6644pp_data->cap[137]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6645pp_data->cap[137]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6646pp_data->cap[137]->NotRange.Usage = 0x0081
6647pp_data->cap[137]->NotRange.Reserved1 = 0x0081
6648pp_data->cap[137]->NotRange.StringIndex = 0
6649pp_data->cap[137]->NotRange.Reserved2 = 0
6650pp_data->cap[137]->NotRange.DesignatorIndex = 0
6651pp_data->cap[137]->NotRange.Reserved3 = 0
6652pp_data->cap[137]->NotRange.DataIndex = 50
6653pp_data->cap[137]->NotRange.Reserved4 = 50
6654pp_data->cap[137]->NotButton.HasNull = 0
6655pp_data->cap[137]->NotButton.Reserved4 = 0x000000
6656pp_data->cap[137]->NotButton.LogicalMin = 0
6657pp_data->cap[137]->NotButton.LogicalMax = 127
6658pp_data->cap[137]->NotButton.PhysicalMin = 0
6659pp_data->cap[137]->NotButton.PhysicalMax = 0
6660pp_data->cap[137]->Units = 0
6661pp_data->cap[137]->UnitsExp = 0
6662
6663pp_data->cap[138]->UsagePage = 0xFF01
6664pp_data->cap[138]->ReportID = 0x80
6665pp_data->cap[138]->BitPosition = 0
6666pp_data->cap[138]->BitSize = 8
6667pp_data->cap[138]->ReportCount = 1
6668pp_data->cap[138]->BytePosition = 0x002B
6669pp_data->cap[138]->BitCount = 8
6670pp_data->cap[138]->BitField = 0x02
6671pp_data->cap[138]->NextBytePosition = 0x002C
6672pp_data->cap[138]->LinkCollection = 0x0003
6673pp_data->cap[138]->LinkUsagePage = 0xFF01
6674pp_data->cap[138]->LinkUsage = 0x0080
6675pp_data->cap[138]->IsMultipleItemsForArray = 0
6676pp_data->cap[138]->IsButtonCap = 0
6677pp_data->cap[138]->IsPadding = 0
6678pp_data->cap[138]->IsAbsolute = 1
6679pp_data->cap[138]->IsRange = 0
6680pp_data->cap[138]->IsAlias = 0
6681pp_data->cap[138]->IsStringRange = 0
6682pp_data->cap[138]->IsDesignatorRange = 0
6683pp_data->cap[138]->Reserved1 = 0x000000
6684pp_data->cap[138]->pp_cap->UnknownTokens[0].Token = 0x00
6685pp_data->cap[138]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6686pp_data->cap[138]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6687pp_data->cap[138]->pp_cap->UnknownTokens[1].Token = 0x00
6688pp_data->cap[138]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6689pp_data->cap[138]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6690pp_data->cap[138]->pp_cap->UnknownTokens[2].Token = 0x00
6691pp_data->cap[138]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6692pp_data->cap[138]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6693pp_data->cap[138]->pp_cap->UnknownTokens[3].Token = 0x00
6694pp_data->cap[138]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6695pp_data->cap[138]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6696pp_data->cap[138]->NotRange.Usage = 0x0081
6697pp_data->cap[138]->NotRange.Reserved1 = 0x0081
6698pp_data->cap[138]->NotRange.StringIndex = 0
6699pp_data->cap[138]->NotRange.Reserved2 = 0
6700pp_data->cap[138]->NotRange.DesignatorIndex = 0
6701pp_data->cap[138]->NotRange.Reserved3 = 0
6702pp_data->cap[138]->NotRange.DataIndex = 51
6703pp_data->cap[138]->NotRange.Reserved4 = 51
6704pp_data->cap[138]->NotButton.HasNull = 0
6705pp_data->cap[138]->NotButton.Reserved4 = 0x000000
6706pp_data->cap[138]->NotButton.LogicalMin = 0
6707pp_data->cap[138]->NotButton.LogicalMax = 127
6708pp_data->cap[138]->NotButton.PhysicalMin = 0
6709pp_data->cap[138]->NotButton.PhysicalMax = 0
6710pp_data->cap[138]->Units = 0
6711pp_data->cap[138]->UnitsExp = 0
6712
6713pp_data->cap[139]->UsagePage = 0xFF01
6714pp_data->cap[139]->ReportID = 0x80
6715pp_data->cap[139]->BitPosition = 0
6716pp_data->cap[139]->BitSize = 8
6717pp_data->cap[139]->ReportCount = 1
6718pp_data->cap[139]->BytePosition = 0x002A
6719pp_data->cap[139]->BitCount = 8
6720pp_data->cap[139]->BitField = 0x02
6721pp_data->cap[139]->NextBytePosition = 0x002B
6722pp_data->cap[139]->LinkCollection = 0x0003
6723pp_data->cap[139]->LinkUsagePage = 0xFF01
6724pp_data->cap[139]->LinkUsage = 0x0080
6725pp_data->cap[139]->IsMultipleItemsForArray = 0
6726pp_data->cap[139]->IsButtonCap = 0
6727pp_data->cap[139]->IsPadding = 0
6728pp_data->cap[139]->IsAbsolute = 1
6729pp_data->cap[139]->IsRange = 0
6730pp_data->cap[139]->IsAlias = 0
6731pp_data->cap[139]->IsStringRange = 0
6732pp_data->cap[139]->IsDesignatorRange = 0
6733pp_data->cap[139]->Reserved1 = 0x000000
6734pp_data->cap[139]->pp_cap->UnknownTokens[0].Token = 0x00
6735pp_data->cap[139]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6736pp_data->cap[139]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6737pp_data->cap[139]->pp_cap->UnknownTokens[1].Token = 0x00
6738pp_data->cap[139]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6739pp_data->cap[139]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6740pp_data->cap[139]->pp_cap->UnknownTokens[2].Token = 0x00
6741pp_data->cap[139]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6742pp_data->cap[139]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6743pp_data->cap[139]->pp_cap->UnknownTokens[3].Token = 0x00
6744pp_data->cap[139]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6745pp_data->cap[139]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6746pp_data->cap[139]->NotRange.Usage = 0x0081
6747pp_data->cap[139]->NotRange.Reserved1 = 0x0081
6748pp_data->cap[139]->NotRange.StringIndex = 0
6749pp_data->cap[139]->NotRange.Reserved2 = 0
6750pp_data->cap[139]->NotRange.DesignatorIndex = 0
6751pp_data->cap[139]->NotRange.Reserved3 = 0
6752pp_data->cap[139]->NotRange.DataIndex = 52
6753pp_data->cap[139]->NotRange.Reserved4 = 52
6754pp_data->cap[139]->NotButton.HasNull = 0
6755pp_data->cap[139]->NotButton.Reserved4 = 0x000000
6756pp_data->cap[139]->NotButton.LogicalMin = 0
6757pp_data->cap[139]->NotButton.LogicalMax = 127
6758pp_data->cap[139]->NotButton.PhysicalMin = 0
6759pp_data->cap[139]->NotButton.PhysicalMax = 0
6760pp_data->cap[139]->Units = 0
6761pp_data->cap[139]->UnitsExp = 0
6762
6763pp_data->cap[140]->UsagePage = 0xFF01
6764pp_data->cap[140]->ReportID = 0x80
6765pp_data->cap[140]->BitPosition = 0
6766pp_data->cap[140]->BitSize = 8
6767pp_data->cap[140]->ReportCount = 1
6768pp_data->cap[140]->BytePosition = 0x0029
6769pp_data->cap[140]->BitCount = 8
6770pp_data->cap[140]->BitField = 0x02
6771pp_data->cap[140]->NextBytePosition = 0x002A
6772pp_data->cap[140]->LinkCollection = 0x0003
6773pp_data->cap[140]->LinkUsagePage = 0xFF01
6774pp_data->cap[140]->LinkUsage = 0x0080
6775pp_data->cap[140]->IsMultipleItemsForArray = 0
6776pp_data->cap[140]->IsButtonCap = 0
6777pp_data->cap[140]->IsPadding = 0
6778pp_data->cap[140]->IsAbsolute = 1
6779pp_data->cap[140]->IsRange = 0
6780pp_data->cap[140]->IsAlias = 0
6781pp_data->cap[140]->IsStringRange = 0
6782pp_data->cap[140]->IsDesignatorRange = 0
6783pp_data->cap[140]->Reserved1 = 0x000000
6784pp_data->cap[140]->pp_cap->UnknownTokens[0].Token = 0x00
6785pp_data->cap[140]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6786pp_data->cap[140]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6787pp_data->cap[140]->pp_cap->UnknownTokens[1].Token = 0x00
6788pp_data->cap[140]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6789pp_data->cap[140]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6790pp_data->cap[140]->pp_cap->UnknownTokens[2].Token = 0x00
6791pp_data->cap[140]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6792pp_data->cap[140]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6793pp_data->cap[140]->pp_cap->UnknownTokens[3].Token = 0x00
6794pp_data->cap[140]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6795pp_data->cap[140]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6796pp_data->cap[140]->NotRange.Usage = 0x0081
6797pp_data->cap[140]->NotRange.Reserved1 = 0x0081
6798pp_data->cap[140]->NotRange.StringIndex = 0
6799pp_data->cap[140]->NotRange.Reserved2 = 0
6800pp_data->cap[140]->NotRange.DesignatorIndex = 0
6801pp_data->cap[140]->NotRange.Reserved3 = 0
6802pp_data->cap[140]->NotRange.DataIndex = 53
6803pp_data->cap[140]->NotRange.Reserved4 = 53
6804pp_data->cap[140]->NotButton.HasNull = 0
6805pp_data->cap[140]->NotButton.Reserved4 = 0x000000
6806pp_data->cap[140]->NotButton.LogicalMin = 0
6807pp_data->cap[140]->NotButton.LogicalMax = 127
6808pp_data->cap[140]->NotButton.PhysicalMin = 0
6809pp_data->cap[140]->NotButton.PhysicalMax = 0
6810pp_data->cap[140]->Units = 0
6811pp_data->cap[140]->UnitsExp = 0
6812
6813pp_data->cap[141]->UsagePage = 0xFF01
6814pp_data->cap[141]->ReportID = 0x80
6815pp_data->cap[141]->BitPosition = 0
6816pp_data->cap[141]->BitSize = 8
6817pp_data->cap[141]->ReportCount = 1
6818pp_data->cap[141]->BytePosition = 0x0028
6819pp_data->cap[141]->BitCount = 8
6820pp_data->cap[141]->BitField = 0x02
6821pp_data->cap[141]->NextBytePosition = 0x0029
6822pp_data->cap[141]->LinkCollection = 0x0003
6823pp_data->cap[141]->LinkUsagePage = 0xFF01
6824pp_data->cap[141]->LinkUsage = 0x0080
6825pp_data->cap[141]->IsMultipleItemsForArray = 0
6826pp_data->cap[141]->IsButtonCap = 0
6827pp_data->cap[141]->IsPadding = 0
6828pp_data->cap[141]->IsAbsolute = 1
6829pp_data->cap[141]->IsRange = 0
6830pp_data->cap[141]->IsAlias = 0
6831pp_data->cap[141]->IsStringRange = 0
6832pp_data->cap[141]->IsDesignatorRange = 0
6833pp_data->cap[141]->Reserved1 = 0x000000
6834pp_data->cap[141]->pp_cap->UnknownTokens[0].Token = 0x00
6835pp_data->cap[141]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6836pp_data->cap[141]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6837pp_data->cap[141]->pp_cap->UnknownTokens[1].Token = 0x00
6838pp_data->cap[141]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6839pp_data->cap[141]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6840pp_data->cap[141]->pp_cap->UnknownTokens[2].Token = 0x00
6841pp_data->cap[141]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6842pp_data->cap[141]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6843pp_data->cap[141]->pp_cap->UnknownTokens[3].Token = 0x00
6844pp_data->cap[141]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6845pp_data->cap[141]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6846pp_data->cap[141]->NotRange.Usage = 0x0081
6847pp_data->cap[141]->NotRange.Reserved1 = 0x0081
6848pp_data->cap[141]->NotRange.StringIndex = 0
6849pp_data->cap[141]->NotRange.Reserved2 = 0
6850pp_data->cap[141]->NotRange.DesignatorIndex = 0
6851pp_data->cap[141]->NotRange.Reserved3 = 0
6852pp_data->cap[141]->NotRange.DataIndex = 54
6853pp_data->cap[141]->NotRange.Reserved4 = 54
6854pp_data->cap[141]->NotButton.HasNull = 0
6855pp_data->cap[141]->NotButton.Reserved4 = 0x000000
6856pp_data->cap[141]->NotButton.LogicalMin = 0
6857pp_data->cap[141]->NotButton.LogicalMax = 127
6858pp_data->cap[141]->NotButton.PhysicalMin = 0
6859pp_data->cap[141]->NotButton.PhysicalMax = 0
6860pp_data->cap[141]->Units = 0
6861pp_data->cap[141]->UnitsExp = 0
6862
6863pp_data->cap[142]->UsagePage = 0xFF01
6864pp_data->cap[142]->ReportID = 0x80
6865pp_data->cap[142]->BitPosition = 0
6866pp_data->cap[142]->BitSize = 8
6867pp_data->cap[142]->ReportCount = 1
6868pp_data->cap[142]->BytePosition = 0x0027
6869pp_data->cap[142]->BitCount = 8
6870pp_data->cap[142]->BitField = 0x02
6871pp_data->cap[142]->NextBytePosition = 0x0028
6872pp_data->cap[142]->LinkCollection = 0x0003
6873pp_data->cap[142]->LinkUsagePage = 0xFF01
6874pp_data->cap[142]->LinkUsage = 0x0080
6875pp_data->cap[142]->IsMultipleItemsForArray = 0
6876pp_data->cap[142]->IsButtonCap = 0
6877pp_data->cap[142]->IsPadding = 0
6878pp_data->cap[142]->IsAbsolute = 1
6879pp_data->cap[142]->IsRange = 0
6880pp_data->cap[142]->IsAlias = 0
6881pp_data->cap[142]->IsStringRange = 0
6882pp_data->cap[142]->IsDesignatorRange = 0
6883pp_data->cap[142]->Reserved1 = 0x000000
6884pp_data->cap[142]->pp_cap->UnknownTokens[0].Token = 0x00
6885pp_data->cap[142]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6886pp_data->cap[142]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6887pp_data->cap[142]->pp_cap->UnknownTokens[1].Token = 0x00
6888pp_data->cap[142]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6889pp_data->cap[142]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6890pp_data->cap[142]->pp_cap->UnknownTokens[2].Token = 0x00
6891pp_data->cap[142]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6892pp_data->cap[142]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6893pp_data->cap[142]->pp_cap->UnknownTokens[3].Token = 0x00
6894pp_data->cap[142]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6895pp_data->cap[142]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6896pp_data->cap[142]->NotRange.Usage = 0x0081
6897pp_data->cap[142]->NotRange.Reserved1 = 0x0081
6898pp_data->cap[142]->NotRange.StringIndex = 0
6899pp_data->cap[142]->NotRange.Reserved2 = 0
6900pp_data->cap[142]->NotRange.DesignatorIndex = 0
6901pp_data->cap[142]->NotRange.Reserved3 = 0
6902pp_data->cap[142]->NotRange.DataIndex = 55
6903pp_data->cap[142]->NotRange.Reserved4 = 55
6904pp_data->cap[142]->NotButton.HasNull = 0
6905pp_data->cap[142]->NotButton.Reserved4 = 0x000000
6906pp_data->cap[142]->NotButton.LogicalMin = 0
6907pp_data->cap[142]->NotButton.LogicalMax = 127
6908pp_data->cap[142]->NotButton.PhysicalMin = 0
6909pp_data->cap[142]->NotButton.PhysicalMax = 0
6910pp_data->cap[142]->Units = 0
6911pp_data->cap[142]->UnitsExp = 0
6912
6913pp_data->cap[143]->UsagePage = 0xFF01
6914pp_data->cap[143]->ReportID = 0x80
6915pp_data->cap[143]->BitPosition = 0
6916pp_data->cap[143]->BitSize = 8
6917pp_data->cap[143]->ReportCount = 1
6918pp_data->cap[143]->BytePosition = 0x0026
6919pp_data->cap[143]->BitCount = 8
6920pp_data->cap[143]->BitField = 0x02
6921pp_data->cap[143]->NextBytePosition = 0x0027
6922pp_data->cap[143]->LinkCollection = 0x0003
6923pp_data->cap[143]->LinkUsagePage = 0xFF01
6924pp_data->cap[143]->LinkUsage = 0x0080
6925pp_data->cap[143]->IsMultipleItemsForArray = 0
6926pp_data->cap[143]->IsButtonCap = 0
6927pp_data->cap[143]->IsPadding = 0
6928pp_data->cap[143]->IsAbsolute = 1
6929pp_data->cap[143]->IsRange = 0
6930pp_data->cap[143]->IsAlias = 0
6931pp_data->cap[143]->IsStringRange = 0
6932pp_data->cap[143]->IsDesignatorRange = 0
6933pp_data->cap[143]->Reserved1 = 0x000000
6934pp_data->cap[143]->pp_cap->UnknownTokens[0].Token = 0x00
6935pp_data->cap[143]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6936pp_data->cap[143]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6937pp_data->cap[143]->pp_cap->UnknownTokens[1].Token = 0x00
6938pp_data->cap[143]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6939pp_data->cap[143]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6940pp_data->cap[143]->pp_cap->UnknownTokens[2].Token = 0x00
6941pp_data->cap[143]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6942pp_data->cap[143]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6943pp_data->cap[143]->pp_cap->UnknownTokens[3].Token = 0x00
6944pp_data->cap[143]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6945pp_data->cap[143]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6946pp_data->cap[143]->NotRange.Usage = 0x0081
6947pp_data->cap[143]->NotRange.Reserved1 = 0x0081
6948pp_data->cap[143]->NotRange.StringIndex = 0
6949pp_data->cap[143]->NotRange.Reserved2 = 0
6950pp_data->cap[143]->NotRange.DesignatorIndex = 0
6951pp_data->cap[143]->NotRange.Reserved3 = 0
6952pp_data->cap[143]->NotRange.DataIndex = 56
6953pp_data->cap[143]->NotRange.Reserved4 = 56
6954pp_data->cap[143]->NotButton.HasNull = 0
6955pp_data->cap[143]->NotButton.Reserved4 = 0x000000
6956pp_data->cap[143]->NotButton.LogicalMin = 0
6957pp_data->cap[143]->NotButton.LogicalMax = 127
6958pp_data->cap[143]->NotButton.PhysicalMin = 0
6959pp_data->cap[143]->NotButton.PhysicalMax = 0
6960pp_data->cap[143]->Units = 0
6961pp_data->cap[143]->UnitsExp = 0
6962
6963pp_data->cap[144]->UsagePage = 0xFF01
6964pp_data->cap[144]->ReportID = 0x80
6965pp_data->cap[144]->BitPosition = 0
6966pp_data->cap[144]->BitSize = 8
6967pp_data->cap[144]->ReportCount = 1
6968pp_data->cap[144]->BytePosition = 0x0025
6969pp_data->cap[144]->BitCount = 8
6970pp_data->cap[144]->BitField = 0x02
6971pp_data->cap[144]->NextBytePosition = 0x0026
6972pp_data->cap[144]->LinkCollection = 0x0003
6973pp_data->cap[144]->LinkUsagePage = 0xFF01
6974pp_data->cap[144]->LinkUsage = 0x0080
6975pp_data->cap[144]->IsMultipleItemsForArray = 0
6976pp_data->cap[144]->IsButtonCap = 0
6977pp_data->cap[144]->IsPadding = 0
6978pp_data->cap[144]->IsAbsolute = 1
6979pp_data->cap[144]->IsRange = 0
6980pp_data->cap[144]->IsAlias = 0
6981pp_data->cap[144]->IsStringRange = 0
6982pp_data->cap[144]->IsDesignatorRange = 0
6983pp_data->cap[144]->Reserved1 = 0x000000
6984pp_data->cap[144]->pp_cap->UnknownTokens[0].Token = 0x00
6985pp_data->cap[144]->pp_cap->UnknownTokens[0].Reserved = 0x000000
6986pp_data->cap[144]->pp_cap->UnknownTokens[0].BitField = 0x00000000
6987pp_data->cap[144]->pp_cap->UnknownTokens[1].Token = 0x00
6988pp_data->cap[144]->pp_cap->UnknownTokens[1].Reserved = 0x000000
6989pp_data->cap[144]->pp_cap->UnknownTokens[1].BitField = 0x00000000
6990pp_data->cap[144]->pp_cap->UnknownTokens[2].Token = 0x00
6991pp_data->cap[144]->pp_cap->UnknownTokens[2].Reserved = 0x000000
6992pp_data->cap[144]->pp_cap->UnknownTokens[2].BitField = 0x00000000
6993pp_data->cap[144]->pp_cap->UnknownTokens[3].Token = 0x00
6994pp_data->cap[144]->pp_cap->UnknownTokens[3].Reserved = 0x000000
6995pp_data->cap[144]->pp_cap->UnknownTokens[3].BitField = 0x00000000
6996pp_data->cap[144]->NotRange.Usage = 0x0081
6997pp_data->cap[144]->NotRange.Reserved1 = 0x0081
6998pp_data->cap[144]->NotRange.StringIndex = 0
6999pp_data->cap[144]->NotRange.Reserved2 = 0
7000pp_data->cap[144]->NotRange.DesignatorIndex = 0
7001pp_data->cap[144]->NotRange.Reserved3 = 0
7002pp_data->cap[144]->NotRange.DataIndex = 57
7003pp_data->cap[144]->NotRange.Reserved4 = 57
7004pp_data->cap[144]->NotButton.HasNull = 0
7005pp_data->cap[144]->NotButton.Reserved4 = 0x000000
7006pp_data->cap[144]->NotButton.LogicalMin = 0
7007pp_data->cap[144]->NotButton.LogicalMax = 127
7008pp_data->cap[144]->NotButton.PhysicalMin = 0
7009pp_data->cap[144]->NotButton.PhysicalMax = 0
7010pp_data->cap[144]->Units = 0
7011pp_data->cap[144]->UnitsExp = 0
7012
7013pp_data->cap[145]->UsagePage = 0xFF01
7014pp_data->cap[145]->ReportID = 0x80
7015pp_data->cap[145]->BitPosition = 0
7016pp_data->cap[145]->BitSize = 8
7017pp_data->cap[145]->ReportCount = 1
7018pp_data->cap[145]->BytePosition = 0x0024
7019pp_data->cap[145]->BitCount = 8
7020pp_data->cap[145]->BitField = 0x02
7021pp_data->cap[145]->NextBytePosition = 0x0025
7022pp_data->cap[145]->LinkCollection = 0x0003
7023pp_data->cap[145]->LinkUsagePage = 0xFF01
7024pp_data->cap[145]->LinkUsage = 0x0080
7025pp_data->cap[145]->IsMultipleItemsForArray = 0
7026pp_data->cap[145]->IsButtonCap = 0
7027pp_data->cap[145]->IsPadding = 0
7028pp_data->cap[145]->IsAbsolute = 1
7029pp_data->cap[145]->IsRange = 0
7030pp_data->cap[145]->IsAlias = 0
7031pp_data->cap[145]->IsStringRange = 0
7032pp_data->cap[145]->IsDesignatorRange = 0
7033pp_data->cap[145]->Reserved1 = 0x000000
7034pp_data->cap[145]->pp_cap->UnknownTokens[0].Token = 0x00
7035pp_data->cap[145]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7036pp_data->cap[145]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7037pp_data->cap[145]->pp_cap->UnknownTokens[1].Token = 0x00
7038pp_data->cap[145]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7039pp_data->cap[145]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7040pp_data->cap[145]->pp_cap->UnknownTokens[2].Token = 0x00
7041pp_data->cap[145]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7042pp_data->cap[145]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7043pp_data->cap[145]->pp_cap->UnknownTokens[3].Token = 0x00
7044pp_data->cap[145]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7045pp_data->cap[145]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7046pp_data->cap[145]->NotRange.Usage = 0x0081
7047pp_data->cap[145]->NotRange.Reserved1 = 0x0081
7048pp_data->cap[145]->NotRange.StringIndex = 0
7049pp_data->cap[145]->NotRange.Reserved2 = 0
7050pp_data->cap[145]->NotRange.DesignatorIndex = 0
7051pp_data->cap[145]->NotRange.Reserved3 = 0
7052pp_data->cap[145]->NotRange.DataIndex = 58
7053pp_data->cap[145]->NotRange.Reserved4 = 58
7054pp_data->cap[145]->NotButton.HasNull = 0
7055pp_data->cap[145]->NotButton.Reserved4 = 0x000000
7056pp_data->cap[145]->NotButton.LogicalMin = 0
7057pp_data->cap[145]->NotButton.LogicalMax = 127
7058pp_data->cap[145]->NotButton.PhysicalMin = 0
7059pp_data->cap[145]->NotButton.PhysicalMax = 0
7060pp_data->cap[145]->Units = 0
7061pp_data->cap[145]->UnitsExp = 0
7062
7063pp_data->cap[146]->UsagePage = 0xFF01
7064pp_data->cap[146]->ReportID = 0x80
7065pp_data->cap[146]->BitPosition = 0
7066pp_data->cap[146]->BitSize = 8
7067pp_data->cap[146]->ReportCount = 1
7068pp_data->cap[146]->BytePosition = 0x0023
7069pp_data->cap[146]->BitCount = 8
7070pp_data->cap[146]->BitField = 0x02
7071pp_data->cap[146]->NextBytePosition = 0x0024
7072pp_data->cap[146]->LinkCollection = 0x0003
7073pp_data->cap[146]->LinkUsagePage = 0xFF01
7074pp_data->cap[146]->LinkUsage = 0x0080
7075pp_data->cap[146]->IsMultipleItemsForArray = 0
7076pp_data->cap[146]->IsButtonCap = 0
7077pp_data->cap[146]->IsPadding = 0
7078pp_data->cap[146]->IsAbsolute = 1
7079pp_data->cap[146]->IsRange = 0
7080pp_data->cap[146]->IsAlias = 0
7081pp_data->cap[146]->IsStringRange = 0
7082pp_data->cap[146]->IsDesignatorRange = 0
7083pp_data->cap[146]->Reserved1 = 0x000000
7084pp_data->cap[146]->pp_cap->UnknownTokens[0].Token = 0x00
7085pp_data->cap[146]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7086pp_data->cap[146]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7087pp_data->cap[146]->pp_cap->UnknownTokens[1].Token = 0x00
7088pp_data->cap[146]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7089pp_data->cap[146]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7090pp_data->cap[146]->pp_cap->UnknownTokens[2].Token = 0x00
7091pp_data->cap[146]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7092pp_data->cap[146]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7093pp_data->cap[146]->pp_cap->UnknownTokens[3].Token = 0x00
7094pp_data->cap[146]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7095pp_data->cap[146]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7096pp_data->cap[146]->NotRange.Usage = 0x0081
7097pp_data->cap[146]->NotRange.Reserved1 = 0x0081
7098pp_data->cap[146]->NotRange.StringIndex = 0
7099pp_data->cap[146]->NotRange.Reserved2 = 0
7100pp_data->cap[146]->NotRange.DesignatorIndex = 0
7101pp_data->cap[146]->NotRange.Reserved3 = 0
7102pp_data->cap[146]->NotRange.DataIndex = 59
7103pp_data->cap[146]->NotRange.Reserved4 = 59
7104pp_data->cap[146]->NotButton.HasNull = 0
7105pp_data->cap[146]->NotButton.Reserved4 = 0x000000
7106pp_data->cap[146]->NotButton.LogicalMin = 0
7107pp_data->cap[146]->NotButton.LogicalMax = 127
7108pp_data->cap[146]->NotButton.PhysicalMin = 0
7109pp_data->cap[146]->NotButton.PhysicalMax = 0
7110pp_data->cap[146]->Units = 0
7111pp_data->cap[146]->UnitsExp = 0
7112
7113pp_data->cap[147]->UsagePage = 0xFF01
7114pp_data->cap[147]->ReportID = 0x80
7115pp_data->cap[147]->BitPosition = 0
7116pp_data->cap[147]->BitSize = 8
7117pp_data->cap[147]->ReportCount = 1
7118pp_data->cap[147]->BytePosition = 0x0022
7119pp_data->cap[147]->BitCount = 8
7120pp_data->cap[147]->BitField = 0x02
7121pp_data->cap[147]->NextBytePosition = 0x0023
7122pp_data->cap[147]->LinkCollection = 0x0003
7123pp_data->cap[147]->LinkUsagePage = 0xFF01
7124pp_data->cap[147]->LinkUsage = 0x0080
7125pp_data->cap[147]->IsMultipleItemsForArray = 0
7126pp_data->cap[147]->IsButtonCap = 0
7127pp_data->cap[147]->IsPadding = 0
7128pp_data->cap[147]->IsAbsolute = 1
7129pp_data->cap[147]->IsRange = 0
7130pp_data->cap[147]->IsAlias = 0
7131pp_data->cap[147]->IsStringRange = 0
7132pp_data->cap[147]->IsDesignatorRange = 0
7133pp_data->cap[147]->Reserved1 = 0x000000
7134pp_data->cap[147]->pp_cap->UnknownTokens[0].Token = 0x00
7135pp_data->cap[147]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7136pp_data->cap[147]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7137pp_data->cap[147]->pp_cap->UnknownTokens[1].Token = 0x00
7138pp_data->cap[147]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7139pp_data->cap[147]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7140pp_data->cap[147]->pp_cap->UnknownTokens[2].Token = 0x00
7141pp_data->cap[147]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7142pp_data->cap[147]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7143pp_data->cap[147]->pp_cap->UnknownTokens[3].Token = 0x00
7144pp_data->cap[147]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7145pp_data->cap[147]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7146pp_data->cap[147]->NotRange.Usage = 0x0081
7147pp_data->cap[147]->NotRange.Reserved1 = 0x0081
7148pp_data->cap[147]->NotRange.StringIndex = 0
7149pp_data->cap[147]->NotRange.Reserved2 = 0
7150pp_data->cap[147]->NotRange.DesignatorIndex = 0
7151pp_data->cap[147]->NotRange.Reserved3 = 0
7152pp_data->cap[147]->NotRange.DataIndex = 60
7153pp_data->cap[147]->NotRange.Reserved4 = 60
7154pp_data->cap[147]->NotButton.HasNull = 0
7155pp_data->cap[147]->NotButton.Reserved4 = 0x000000
7156pp_data->cap[147]->NotButton.LogicalMin = 0
7157pp_data->cap[147]->NotButton.LogicalMax = 127
7158pp_data->cap[147]->NotButton.PhysicalMin = 0
7159pp_data->cap[147]->NotButton.PhysicalMax = 0
7160pp_data->cap[147]->Units = 0
7161pp_data->cap[147]->UnitsExp = 0
7162
7163pp_data->cap[148]->UsagePage = 0xFF01
7164pp_data->cap[148]->ReportID = 0x80
7165pp_data->cap[148]->BitPosition = 0
7166pp_data->cap[148]->BitSize = 8
7167pp_data->cap[148]->ReportCount = 1
7168pp_data->cap[148]->BytePosition = 0x0021
7169pp_data->cap[148]->BitCount = 8
7170pp_data->cap[148]->BitField = 0x02
7171pp_data->cap[148]->NextBytePosition = 0x0022
7172pp_data->cap[148]->LinkCollection = 0x0003
7173pp_data->cap[148]->LinkUsagePage = 0xFF01
7174pp_data->cap[148]->LinkUsage = 0x0080
7175pp_data->cap[148]->IsMultipleItemsForArray = 0
7176pp_data->cap[148]->IsButtonCap = 0
7177pp_data->cap[148]->IsPadding = 0
7178pp_data->cap[148]->IsAbsolute = 1
7179pp_data->cap[148]->IsRange = 0
7180pp_data->cap[148]->IsAlias = 0
7181pp_data->cap[148]->IsStringRange = 0
7182pp_data->cap[148]->IsDesignatorRange = 0
7183pp_data->cap[148]->Reserved1 = 0x000000
7184pp_data->cap[148]->pp_cap->UnknownTokens[0].Token = 0x00
7185pp_data->cap[148]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7186pp_data->cap[148]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7187pp_data->cap[148]->pp_cap->UnknownTokens[1].Token = 0x00
7188pp_data->cap[148]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7189pp_data->cap[148]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7190pp_data->cap[148]->pp_cap->UnknownTokens[2].Token = 0x00
7191pp_data->cap[148]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7192pp_data->cap[148]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7193pp_data->cap[148]->pp_cap->UnknownTokens[3].Token = 0x00
7194pp_data->cap[148]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7195pp_data->cap[148]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7196pp_data->cap[148]->NotRange.Usage = 0x0081
7197pp_data->cap[148]->NotRange.Reserved1 = 0x0081
7198pp_data->cap[148]->NotRange.StringIndex = 0
7199pp_data->cap[148]->NotRange.Reserved2 = 0
7200pp_data->cap[148]->NotRange.DesignatorIndex = 0
7201pp_data->cap[148]->NotRange.Reserved3 = 0
7202pp_data->cap[148]->NotRange.DataIndex = 61
7203pp_data->cap[148]->NotRange.Reserved4 = 61
7204pp_data->cap[148]->NotButton.HasNull = 0
7205pp_data->cap[148]->NotButton.Reserved4 = 0x000000
7206pp_data->cap[148]->NotButton.LogicalMin = 0
7207pp_data->cap[148]->NotButton.LogicalMax = 127
7208pp_data->cap[148]->NotButton.PhysicalMin = 0
7209pp_data->cap[148]->NotButton.PhysicalMax = 0
7210pp_data->cap[148]->Units = 0
7211pp_data->cap[148]->UnitsExp = 0
7212
7213pp_data->cap[149]->UsagePage = 0xFF01
7214pp_data->cap[149]->ReportID = 0x80
7215pp_data->cap[149]->BitPosition = 0
7216pp_data->cap[149]->BitSize = 8
7217pp_data->cap[149]->ReportCount = 1
7218pp_data->cap[149]->BytePosition = 0x0020
7219pp_data->cap[149]->BitCount = 8
7220pp_data->cap[149]->BitField = 0x02
7221pp_data->cap[149]->NextBytePosition = 0x0021
7222pp_data->cap[149]->LinkCollection = 0x0003
7223pp_data->cap[149]->LinkUsagePage = 0xFF01
7224pp_data->cap[149]->LinkUsage = 0x0080
7225pp_data->cap[149]->IsMultipleItemsForArray = 0
7226pp_data->cap[149]->IsButtonCap = 0
7227pp_data->cap[149]->IsPadding = 0
7228pp_data->cap[149]->IsAbsolute = 1
7229pp_data->cap[149]->IsRange = 0
7230pp_data->cap[149]->IsAlias = 0
7231pp_data->cap[149]->IsStringRange = 0
7232pp_data->cap[149]->IsDesignatorRange = 0
7233pp_data->cap[149]->Reserved1 = 0x000000
7234pp_data->cap[149]->pp_cap->UnknownTokens[0].Token = 0x00
7235pp_data->cap[149]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7236pp_data->cap[149]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7237pp_data->cap[149]->pp_cap->UnknownTokens[1].Token = 0x00
7238pp_data->cap[149]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7239pp_data->cap[149]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7240pp_data->cap[149]->pp_cap->UnknownTokens[2].Token = 0x00
7241pp_data->cap[149]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7242pp_data->cap[149]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7243pp_data->cap[149]->pp_cap->UnknownTokens[3].Token = 0x00
7244pp_data->cap[149]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7245pp_data->cap[149]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7246pp_data->cap[149]->NotRange.Usage = 0x0081
7247pp_data->cap[149]->NotRange.Reserved1 = 0x0081
7248pp_data->cap[149]->NotRange.StringIndex = 0
7249pp_data->cap[149]->NotRange.Reserved2 = 0
7250pp_data->cap[149]->NotRange.DesignatorIndex = 0
7251pp_data->cap[149]->NotRange.Reserved3 = 0
7252pp_data->cap[149]->NotRange.DataIndex = 62
7253pp_data->cap[149]->NotRange.Reserved4 = 62
7254pp_data->cap[149]->NotButton.HasNull = 0
7255pp_data->cap[149]->NotButton.Reserved4 = 0x000000
7256pp_data->cap[149]->NotButton.LogicalMin = 0
7257pp_data->cap[149]->NotButton.LogicalMax = 127
7258pp_data->cap[149]->NotButton.PhysicalMin = 0
7259pp_data->cap[149]->NotButton.PhysicalMax = 0
7260pp_data->cap[149]->Units = 0
7261pp_data->cap[149]->UnitsExp = 0
7262
7263pp_data->cap[150]->UsagePage = 0xFF01
7264pp_data->cap[150]->ReportID = 0x80
7265pp_data->cap[150]->BitPosition = 0
7266pp_data->cap[150]->BitSize = 8
7267pp_data->cap[150]->ReportCount = 1
7268pp_data->cap[150]->BytePosition = 0x001F
7269pp_data->cap[150]->BitCount = 8
7270pp_data->cap[150]->BitField = 0x02
7271pp_data->cap[150]->NextBytePosition = 0x0020
7272pp_data->cap[150]->LinkCollection = 0x0003
7273pp_data->cap[150]->LinkUsagePage = 0xFF01
7274pp_data->cap[150]->LinkUsage = 0x0080
7275pp_data->cap[150]->IsMultipleItemsForArray = 0
7276pp_data->cap[150]->IsButtonCap = 0
7277pp_data->cap[150]->IsPadding = 0
7278pp_data->cap[150]->IsAbsolute = 1
7279pp_data->cap[150]->IsRange = 0
7280pp_data->cap[150]->IsAlias = 0
7281pp_data->cap[150]->IsStringRange = 0
7282pp_data->cap[150]->IsDesignatorRange = 0
7283pp_data->cap[150]->Reserved1 = 0x000000
7284pp_data->cap[150]->pp_cap->UnknownTokens[0].Token = 0x00
7285pp_data->cap[150]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7286pp_data->cap[150]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7287pp_data->cap[150]->pp_cap->UnknownTokens[1].Token = 0x00
7288pp_data->cap[150]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7289pp_data->cap[150]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7290pp_data->cap[150]->pp_cap->UnknownTokens[2].Token = 0x00
7291pp_data->cap[150]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7292pp_data->cap[150]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7293pp_data->cap[150]->pp_cap->UnknownTokens[3].Token = 0x00
7294pp_data->cap[150]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7295pp_data->cap[150]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7296pp_data->cap[150]->NotRange.Usage = 0x0081
7297pp_data->cap[150]->NotRange.Reserved1 = 0x0081
7298pp_data->cap[150]->NotRange.StringIndex = 0
7299pp_data->cap[150]->NotRange.Reserved2 = 0
7300pp_data->cap[150]->NotRange.DesignatorIndex = 0
7301pp_data->cap[150]->NotRange.Reserved3 = 0
7302pp_data->cap[150]->NotRange.DataIndex = 63
7303pp_data->cap[150]->NotRange.Reserved4 = 63
7304pp_data->cap[150]->NotButton.HasNull = 0
7305pp_data->cap[150]->NotButton.Reserved4 = 0x000000
7306pp_data->cap[150]->NotButton.LogicalMin = 0
7307pp_data->cap[150]->NotButton.LogicalMax = 127
7308pp_data->cap[150]->NotButton.PhysicalMin = 0
7309pp_data->cap[150]->NotButton.PhysicalMax = 0
7310pp_data->cap[150]->Units = 0
7311pp_data->cap[150]->UnitsExp = 0
7312
7313pp_data->cap[151]->UsagePage = 0xFF01
7314pp_data->cap[151]->ReportID = 0x80
7315pp_data->cap[151]->BitPosition = 0
7316pp_data->cap[151]->BitSize = 8
7317pp_data->cap[151]->ReportCount = 1
7318pp_data->cap[151]->BytePosition = 0x001E
7319pp_data->cap[151]->BitCount = 8
7320pp_data->cap[151]->BitField = 0x02
7321pp_data->cap[151]->NextBytePosition = 0x001F
7322pp_data->cap[151]->LinkCollection = 0x0003
7323pp_data->cap[151]->LinkUsagePage = 0xFF01
7324pp_data->cap[151]->LinkUsage = 0x0080
7325pp_data->cap[151]->IsMultipleItemsForArray = 0
7326pp_data->cap[151]->IsButtonCap = 0
7327pp_data->cap[151]->IsPadding = 0
7328pp_data->cap[151]->IsAbsolute = 1
7329pp_data->cap[151]->IsRange = 0
7330pp_data->cap[151]->IsAlias = 0
7331pp_data->cap[151]->IsStringRange = 0
7332pp_data->cap[151]->IsDesignatorRange = 0
7333pp_data->cap[151]->Reserved1 = 0x000000
7334pp_data->cap[151]->pp_cap->UnknownTokens[0].Token = 0x00
7335pp_data->cap[151]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7336pp_data->cap[151]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7337pp_data->cap[151]->pp_cap->UnknownTokens[1].Token = 0x00
7338pp_data->cap[151]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7339pp_data->cap[151]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7340pp_data->cap[151]->pp_cap->UnknownTokens[2].Token = 0x00
7341pp_data->cap[151]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7342pp_data->cap[151]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7343pp_data->cap[151]->pp_cap->UnknownTokens[3].Token = 0x00
7344pp_data->cap[151]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7345pp_data->cap[151]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7346pp_data->cap[151]->NotRange.Usage = 0x0081
7347pp_data->cap[151]->NotRange.Reserved1 = 0x0081
7348pp_data->cap[151]->NotRange.StringIndex = 0
7349pp_data->cap[151]->NotRange.Reserved2 = 0
7350pp_data->cap[151]->NotRange.DesignatorIndex = 0
7351pp_data->cap[151]->NotRange.Reserved3 = 0
7352pp_data->cap[151]->NotRange.DataIndex = 64
7353pp_data->cap[151]->NotRange.Reserved4 = 64
7354pp_data->cap[151]->NotButton.HasNull = 0
7355pp_data->cap[151]->NotButton.Reserved4 = 0x000000
7356pp_data->cap[151]->NotButton.LogicalMin = 0
7357pp_data->cap[151]->NotButton.LogicalMax = 127
7358pp_data->cap[151]->NotButton.PhysicalMin = 0
7359pp_data->cap[151]->NotButton.PhysicalMax = 0
7360pp_data->cap[151]->Units = 0
7361pp_data->cap[151]->UnitsExp = 0
7362
7363pp_data->cap[152]->UsagePage = 0xFF01
7364pp_data->cap[152]->ReportID = 0x80
7365pp_data->cap[152]->BitPosition = 0
7366pp_data->cap[152]->BitSize = 8
7367pp_data->cap[152]->ReportCount = 1
7368pp_data->cap[152]->BytePosition = 0x001D
7369pp_data->cap[152]->BitCount = 8
7370pp_data->cap[152]->BitField = 0x02
7371pp_data->cap[152]->NextBytePosition = 0x001E
7372pp_data->cap[152]->LinkCollection = 0x0003
7373pp_data->cap[152]->LinkUsagePage = 0xFF01
7374pp_data->cap[152]->LinkUsage = 0x0080
7375pp_data->cap[152]->IsMultipleItemsForArray = 0
7376pp_data->cap[152]->IsButtonCap = 0
7377pp_data->cap[152]->IsPadding = 0
7378pp_data->cap[152]->IsAbsolute = 1
7379pp_data->cap[152]->IsRange = 0
7380pp_data->cap[152]->IsAlias = 0
7381pp_data->cap[152]->IsStringRange = 0
7382pp_data->cap[152]->IsDesignatorRange = 0
7383pp_data->cap[152]->Reserved1 = 0x000000
7384pp_data->cap[152]->pp_cap->UnknownTokens[0].Token = 0x00
7385pp_data->cap[152]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7386pp_data->cap[152]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7387pp_data->cap[152]->pp_cap->UnknownTokens[1].Token = 0x00
7388pp_data->cap[152]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7389pp_data->cap[152]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7390pp_data->cap[152]->pp_cap->UnknownTokens[2].Token = 0x00
7391pp_data->cap[152]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7392pp_data->cap[152]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7393pp_data->cap[152]->pp_cap->UnknownTokens[3].Token = 0x00
7394pp_data->cap[152]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7395pp_data->cap[152]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7396pp_data->cap[152]->NotRange.Usage = 0x0081
7397pp_data->cap[152]->NotRange.Reserved1 = 0x0081
7398pp_data->cap[152]->NotRange.StringIndex = 0
7399pp_data->cap[152]->NotRange.Reserved2 = 0
7400pp_data->cap[152]->NotRange.DesignatorIndex = 0
7401pp_data->cap[152]->NotRange.Reserved3 = 0
7402pp_data->cap[152]->NotRange.DataIndex = 65
7403pp_data->cap[152]->NotRange.Reserved4 = 65
7404pp_data->cap[152]->NotButton.HasNull = 0
7405pp_data->cap[152]->NotButton.Reserved4 = 0x000000
7406pp_data->cap[152]->NotButton.LogicalMin = 0
7407pp_data->cap[152]->NotButton.LogicalMax = 127
7408pp_data->cap[152]->NotButton.PhysicalMin = 0
7409pp_data->cap[152]->NotButton.PhysicalMax = 0
7410pp_data->cap[152]->Units = 0
7411pp_data->cap[152]->UnitsExp = 0
7412
7413pp_data->cap[153]->UsagePage = 0xFF01
7414pp_data->cap[153]->ReportID = 0x80
7415pp_data->cap[153]->BitPosition = 0
7416pp_data->cap[153]->BitSize = 8
7417pp_data->cap[153]->ReportCount = 1
7418pp_data->cap[153]->BytePosition = 0x001C
7419pp_data->cap[153]->BitCount = 8
7420pp_data->cap[153]->BitField = 0x02
7421pp_data->cap[153]->NextBytePosition = 0x001D
7422pp_data->cap[153]->LinkCollection = 0x0003
7423pp_data->cap[153]->LinkUsagePage = 0xFF01
7424pp_data->cap[153]->LinkUsage = 0x0080
7425pp_data->cap[153]->IsMultipleItemsForArray = 0
7426pp_data->cap[153]->IsButtonCap = 0
7427pp_data->cap[153]->IsPadding = 0
7428pp_data->cap[153]->IsAbsolute = 1
7429pp_data->cap[153]->IsRange = 0
7430pp_data->cap[153]->IsAlias = 0
7431pp_data->cap[153]->IsStringRange = 0
7432pp_data->cap[153]->IsDesignatorRange = 0
7433pp_data->cap[153]->Reserved1 = 0x000000
7434pp_data->cap[153]->pp_cap->UnknownTokens[0].Token = 0x00
7435pp_data->cap[153]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7436pp_data->cap[153]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7437pp_data->cap[153]->pp_cap->UnknownTokens[1].Token = 0x00
7438pp_data->cap[153]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7439pp_data->cap[153]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7440pp_data->cap[153]->pp_cap->UnknownTokens[2].Token = 0x00
7441pp_data->cap[153]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7442pp_data->cap[153]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7443pp_data->cap[153]->pp_cap->UnknownTokens[3].Token = 0x00
7444pp_data->cap[153]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7445pp_data->cap[153]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7446pp_data->cap[153]->NotRange.Usage = 0x0081
7447pp_data->cap[153]->NotRange.Reserved1 = 0x0081
7448pp_data->cap[153]->NotRange.StringIndex = 0
7449pp_data->cap[153]->NotRange.Reserved2 = 0
7450pp_data->cap[153]->NotRange.DesignatorIndex = 0
7451pp_data->cap[153]->NotRange.Reserved3 = 0
7452pp_data->cap[153]->NotRange.DataIndex = 66
7453pp_data->cap[153]->NotRange.Reserved4 = 66
7454pp_data->cap[153]->NotButton.HasNull = 0
7455pp_data->cap[153]->NotButton.Reserved4 = 0x000000
7456pp_data->cap[153]->NotButton.LogicalMin = 0
7457pp_data->cap[153]->NotButton.LogicalMax = 127
7458pp_data->cap[153]->NotButton.PhysicalMin = 0
7459pp_data->cap[153]->NotButton.PhysicalMax = 0
7460pp_data->cap[153]->Units = 0
7461pp_data->cap[153]->UnitsExp = 0
7462
7463pp_data->cap[154]->UsagePage = 0xFF01
7464pp_data->cap[154]->ReportID = 0x80
7465pp_data->cap[154]->BitPosition = 0
7466pp_data->cap[154]->BitSize = 8
7467pp_data->cap[154]->ReportCount = 1
7468pp_data->cap[154]->BytePosition = 0x001B
7469pp_data->cap[154]->BitCount = 8
7470pp_data->cap[154]->BitField = 0x02
7471pp_data->cap[154]->NextBytePosition = 0x001C
7472pp_data->cap[154]->LinkCollection = 0x0003
7473pp_data->cap[154]->LinkUsagePage = 0xFF01
7474pp_data->cap[154]->LinkUsage = 0x0080
7475pp_data->cap[154]->IsMultipleItemsForArray = 0
7476pp_data->cap[154]->IsButtonCap = 0
7477pp_data->cap[154]->IsPadding = 0
7478pp_data->cap[154]->IsAbsolute = 1
7479pp_data->cap[154]->IsRange = 0
7480pp_data->cap[154]->IsAlias = 0
7481pp_data->cap[154]->IsStringRange = 0
7482pp_data->cap[154]->IsDesignatorRange = 0
7483pp_data->cap[154]->Reserved1 = 0x000000
7484pp_data->cap[154]->pp_cap->UnknownTokens[0].Token = 0x00
7485pp_data->cap[154]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7486pp_data->cap[154]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7487pp_data->cap[154]->pp_cap->UnknownTokens[1].Token = 0x00
7488pp_data->cap[154]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7489pp_data->cap[154]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7490pp_data->cap[154]->pp_cap->UnknownTokens[2].Token = 0x00
7491pp_data->cap[154]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7492pp_data->cap[154]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7493pp_data->cap[154]->pp_cap->UnknownTokens[3].Token = 0x00
7494pp_data->cap[154]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7495pp_data->cap[154]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7496pp_data->cap[154]->NotRange.Usage = 0x0081
7497pp_data->cap[154]->NotRange.Reserved1 = 0x0081
7498pp_data->cap[154]->NotRange.StringIndex = 0
7499pp_data->cap[154]->NotRange.Reserved2 = 0
7500pp_data->cap[154]->NotRange.DesignatorIndex = 0
7501pp_data->cap[154]->NotRange.Reserved3 = 0
7502pp_data->cap[154]->NotRange.DataIndex = 67
7503pp_data->cap[154]->NotRange.Reserved4 = 67
7504pp_data->cap[154]->NotButton.HasNull = 0
7505pp_data->cap[154]->NotButton.Reserved4 = 0x000000
7506pp_data->cap[154]->NotButton.LogicalMin = 0
7507pp_data->cap[154]->NotButton.LogicalMax = 127
7508pp_data->cap[154]->NotButton.PhysicalMin = 0
7509pp_data->cap[154]->NotButton.PhysicalMax = 0
7510pp_data->cap[154]->Units = 0
7511pp_data->cap[154]->UnitsExp = 0
7512
7513pp_data->cap[155]->UsagePage = 0xFF01
7514pp_data->cap[155]->ReportID = 0x80
7515pp_data->cap[155]->BitPosition = 0
7516pp_data->cap[155]->BitSize = 8
7517pp_data->cap[155]->ReportCount = 1
7518pp_data->cap[155]->BytePosition = 0x001A
7519pp_data->cap[155]->BitCount = 8
7520pp_data->cap[155]->BitField = 0x02
7521pp_data->cap[155]->NextBytePosition = 0x001B
7522pp_data->cap[155]->LinkCollection = 0x0003
7523pp_data->cap[155]->LinkUsagePage = 0xFF01
7524pp_data->cap[155]->LinkUsage = 0x0080
7525pp_data->cap[155]->IsMultipleItemsForArray = 0
7526pp_data->cap[155]->IsButtonCap = 0
7527pp_data->cap[155]->IsPadding = 0
7528pp_data->cap[155]->IsAbsolute = 1
7529pp_data->cap[155]->IsRange = 0
7530pp_data->cap[155]->IsAlias = 0
7531pp_data->cap[155]->IsStringRange = 0
7532pp_data->cap[155]->IsDesignatorRange = 0
7533pp_data->cap[155]->Reserved1 = 0x000000
7534pp_data->cap[155]->pp_cap->UnknownTokens[0].Token = 0x00
7535pp_data->cap[155]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7536pp_data->cap[155]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7537pp_data->cap[155]->pp_cap->UnknownTokens[1].Token = 0x00
7538pp_data->cap[155]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7539pp_data->cap[155]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7540pp_data->cap[155]->pp_cap->UnknownTokens[2].Token = 0x00
7541pp_data->cap[155]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7542pp_data->cap[155]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7543pp_data->cap[155]->pp_cap->UnknownTokens[3].Token = 0x00
7544pp_data->cap[155]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7545pp_data->cap[155]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7546pp_data->cap[155]->NotRange.Usage = 0x0081
7547pp_data->cap[155]->NotRange.Reserved1 = 0x0081
7548pp_data->cap[155]->NotRange.StringIndex = 0
7549pp_data->cap[155]->NotRange.Reserved2 = 0
7550pp_data->cap[155]->NotRange.DesignatorIndex = 0
7551pp_data->cap[155]->NotRange.Reserved3 = 0
7552pp_data->cap[155]->NotRange.DataIndex = 68
7553pp_data->cap[155]->NotRange.Reserved4 = 68
7554pp_data->cap[155]->NotButton.HasNull = 0
7555pp_data->cap[155]->NotButton.Reserved4 = 0x000000
7556pp_data->cap[155]->NotButton.LogicalMin = 0
7557pp_data->cap[155]->NotButton.LogicalMax = 127
7558pp_data->cap[155]->NotButton.PhysicalMin = 0
7559pp_data->cap[155]->NotButton.PhysicalMax = 0
7560pp_data->cap[155]->Units = 0
7561pp_data->cap[155]->UnitsExp = 0
7562
7563pp_data->cap[156]->UsagePage = 0xFF01
7564pp_data->cap[156]->ReportID = 0x80
7565pp_data->cap[156]->BitPosition = 0
7566pp_data->cap[156]->BitSize = 8
7567pp_data->cap[156]->ReportCount = 1
7568pp_data->cap[156]->BytePosition = 0x0019
7569pp_data->cap[156]->BitCount = 8
7570pp_data->cap[156]->BitField = 0x02
7571pp_data->cap[156]->NextBytePosition = 0x001A
7572pp_data->cap[156]->LinkCollection = 0x0003
7573pp_data->cap[156]->LinkUsagePage = 0xFF01
7574pp_data->cap[156]->LinkUsage = 0x0080
7575pp_data->cap[156]->IsMultipleItemsForArray = 0
7576pp_data->cap[156]->IsButtonCap = 0
7577pp_data->cap[156]->IsPadding = 0
7578pp_data->cap[156]->IsAbsolute = 1
7579pp_data->cap[156]->IsRange = 0
7580pp_data->cap[156]->IsAlias = 0
7581pp_data->cap[156]->IsStringRange = 0
7582pp_data->cap[156]->IsDesignatorRange = 0
7583pp_data->cap[156]->Reserved1 = 0x000000
7584pp_data->cap[156]->pp_cap->UnknownTokens[0].Token = 0x00
7585pp_data->cap[156]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7586pp_data->cap[156]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7587pp_data->cap[156]->pp_cap->UnknownTokens[1].Token = 0x00
7588pp_data->cap[156]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7589pp_data->cap[156]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7590pp_data->cap[156]->pp_cap->UnknownTokens[2].Token = 0x00
7591pp_data->cap[156]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7592pp_data->cap[156]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7593pp_data->cap[156]->pp_cap->UnknownTokens[3].Token = 0x00
7594pp_data->cap[156]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7595pp_data->cap[156]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7596pp_data->cap[156]->NotRange.Usage = 0x0081
7597pp_data->cap[156]->NotRange.Reserved1 = 0x0081
7598pp_data->cap[156]->NotRange.StringIndex = 0
7599pp_data->cap[156]->NotRange.Reserved2 = 0
7600pp_data->cap[156]->NotRange.DesignatorIndex = 0
7601pp_data->cap[156]->NotRange.Reserved3 = 0
7602pp_data->cap[156]->NotRange.DataIndex = 69
7603pp_data->cap[156]->NotRange.Reserved4 = 69
7604pp_data->cap[156]->NotButton.HasNull = 0
7605pp_data->cap[156]->NotButton.Reserved4 = 0x000000
7606pp_data->cap[156]->NotButton.LogicalMin = 0
7607pp_data->cap[156]->NotButton.LogicalMax = 127
7608pp_data->cap[156]->NotButton.PhysicalMin = 0
7609pp_data->cap[156]->NotButton.PhysicalMax = 0
7610pp_data->cap[156]->Units = 0
7611pp_data->cap[156]->UnitsExp = 0
7612
7613pp_data->cap[157]->UsagePage = 0xFF01
7614pp_data->cap[157]->ReportID = 0x80
7615pp_data->cap[157]->BitPosition = 0
7616pp_data->cap[157]->BitSize = 8
7617pp_data->cap[157]->ReportCount = 1
7618pp_data->cap[157]->BytePosition = 0x0018
7619pp_data->cap[157]->BitCount = 8
7620pp_data->cap[157]->BitField = 0x02
7621pp_data->cap[157]->NextBytePosition = 0x0019
7622pp_data->cap[157]->LinkCollection = 0x0003
7623pp_data->cap[157]->LinkUsagePage = 0xFF01
7624pp_data->cap[157]->LinkUsage = 0x0080
7625pp_data->cap[157]->IsMultipleItemsForArray = 0
7626pp_data->cap[157]->IsButtonCap = 0
7627pp_data->cap[157]->IsPadding = 0
7628pp_data->cap[157]->IsAbsolute = 1
7629pp_data->cap[157]->IsRange = 0
7630pp_data->cap[157]->IsAlias = 0
7631pp_data->cap[157]->IsStringRange = 0
7632pp_data->cap[157]->IsDesignatorRange = 0
7633pp_data->cap[157]->Reserved1 = 0x000000
7634pp_data->cap[157]->pp_cap->UnknownTokens[0].Token = 0x00
7635pp_data->cap[157]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7636pp_data->cap[157]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7637pp_data->cap[157]->pp_cap->UnknownTokens[1].Token = 0x00
7638pp_data->cap[157]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7639pp_data->cap[157]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7640pp_data->cap[157]->pp_cap->UnknownTokens[2].Token = 0x00
7641pp_data->cap[157]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7642pp_data->cap[157]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7643pp_data->cap[157]->pp_cap->UnknownTokens[3].Token = 0x00
7644pp_data->cap[157]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7645pp_data->cap[157]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7646pp_data->cap[157]->NotRange.Usage = 0x0081
7647pp_data->cap[157]->NotRange.Reserved1 = 0x0081
7648pp_data->cap[157]->NotRange.StringIndex = 0
7649pp_data->cap[157]->NotRange.Reserved2 = 0
7650pp_data->cap[157]->NotRange.DesignatorIndex = 0
7651pp_data->cap[157]->NotRange.Reserved3 = 0
7652pp_data->cap[157]->NotRange.DataIndex = 70
7653pp_data->cap[157]->NotRange.Reserved4 = 70
7654pp_data->cap[157]->NotButton.HasNull = 0
7655pp_data->cap[157]->NotButton.Reserved4 = 0x000000
7656pp_data->cap[157]->NotButton.LogicalMin = 0
7657pp_data->cap[157]->NotButton.LogicalMax = 127
7658pp_data->cap[157]->NotButton.PhysicalMin = 0
7659pp_data->cap[157]->NotButton.PhysicalMax = 0
7660pp_data->cap[157]->Units = 0
7661pp_data->cap[157]->UnitsExp = 0
7662
7663pp_data->cap[158]->UsagePage = 0xFF01
7664pp_data->cap[158]->ReportID = 0x80
7665pp_data->cap[158]->BitPosition = 0
7666pp_data->cap[158]->BitSize = 8
7667pp_data->cap[158]->ReportCount = 1
7668pp_data->cap[158]->BytePosition = 0x0017
7669pp_data->cap[158]->BitCount = 8
7670pp_data->cap[158]->BitField = 0x02
7671pp_data->cap[158]->NextBytePosition = 0x0018
7672pp_data->cap[158]->LinkCollection = 0x0003
7673pp_data->cap[158]->LinkUsagePage = 0xFF01
7674pp_data->cap[158]->LinkUsage = 0x0080
7675pp_data->cap[158]->IsMultipleItemsForArray = 0
7676pp_data->cap[158]->IsButtonCap = 0
7677pp_data->cap[158]->IsPadding = 0
7678pp_data->cap[158]->IsAbsolute = 1
7679pp_data->cap[158]->IsRange = 0
7680pp_data->cap[158]->IsAlias = 0
7681pp_data->cap[158]->IsStringRange = 0
7682pp_data->cap[158]->IsDesignatorRange = 0
7683pp_data->cap[158]->Reserved1 = 0x000000
7684pp_data->cap[158]->pp_cap->UnknownTokens[0].Token = 0x00
7685pp_data->cap[158]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7686pp_data->cap[158]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7687pp_data->cap[158]->pp_cap->UnknownTokens[1].Token = 0x00
7688pp_data->cap[158]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7689pp_data->cap[158]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7690pp_data->cap[158]->pp_cap->UnknownTokens[2].Token = 0x00
7691pp_data->cap[158]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7692pp_data->cap[158]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7693pp_data->cap[158]->pp_cap->UnknownTokens[3].Token = 0x00
7694pp_data->cap[158]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7695pp_data->cap[158]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7696pp_data->cap[158]->NotRange.Usage = 0x0081
7697pp_data->cap[158]->NotRange.Reserved1 = 0x0081
7698pp_data->cap[158]->NotRange.StringIndex = 0
7699pp_data->cap[158]->NotRange.Reserved2 = 0
7700pp_data->cap[158]->NotRange.DesignatorIndex = 0
7701pp_data->cap[158]->NotRange.Reserved3 = 0
7702pp_data->cap[158]->NotRange.DataIndex = 71
7703pp_data->cap[158]->NotRange.Reserved4 = 71
7704pp_data->cap[158]->NotButton.HasNull = 0
7705pp_data->cap[158]->NotButton.Reserved4 = 0x000000
7706pp_data->cap[158]->NotButton.LogicalMin = 0
7707pp_data->cap[158]->NotButton.LogicalMax = 127
7708pp_data->cap[158]->NotButton.PhysicalMin = 0
7709pp_data->cap[158]->NotButton.PhysicalMax = 0
7710pp_data->cap[158]->Units = 0
7711pp_data->cap[158]->UnitsExp = 0
7712
7713pp_data->cap[159]->UsagePage = 0xFF01
7714pp_data->cap[159]->ReportID = 0x80
7715pp_data->cap[159]->BitPosition = 0
7716pp_data->cap[159]->BitSize = 8
7717pp_data->cap[159]->ReportCount = 1
7718pp_data->cap[159]->BytePosition = 0x0016
7719pp_data->cap[159]->BitCount = 8
7720pp_data->cap[159]->BitField = 0x02
7721pp_data->cap[159]->NextBytePosition = 0x0017
7722pp_data->cap[159]->LinkCollection = 0x0003
7723pp_data->cap[159]->LinkUsagePage = 0xFF01
7724pp_data->cap[159]->LinkUsage = 0x0080
7725pp_data->cap[159]->IsMultipleItemsForArray = 0
7726pp_data->cap[159]->IsButtonCap = 0
7727pp_data->cap[159]->IsPadding = 0
7728pp_data->cap[159]->IsAbsolute = 1
7729pp_data->cap[159]->IsRange = 0
7730pp_data->cap[159]->IsAlias = 0
7731pp_data->cap[159]->IsStringRange = 0
7732pp_data->cap[159]->IsDesignatorRange = 0
7733pp_data->cap[159]->Reserved1 = 0x000000
7734pp_data->cap[159]->pp_cap->UnknownTokens[0].Token = 0x00
7735pp_data->cap[159]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7736pp_data->cap[159]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7737pp_data->cap[159]->pp_cap->UnknownTokens[1].Token = 0x00
7738pp_data->cap[159]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7739pp_data->cap[159]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7740pp_data->cap[159]->pp_cap->UnknownTokens[2].Token = 0x00
7741pp_data->cap[159]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7742pp_data->cap[159]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7743pp_data->cap[159]->pp_cap->UnknownTokens[3].Token = 0x00
7744pp_data->cap[159]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7745pp_data->cap[159]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7746pp_data->cap[159]->NotRange.Usage = 0x0081
7747pp_data->cap[159]->NotRange.Reserved1 = 0x0081
7748pp_data->cap[159]->NotRange.StringIndex = 0
7749pp_data->cap[159]->NotRange.Reserved2 = 0
7750pp_data->cap[159]->NotRange.DesignatorIndex = 0
7751pp_data->cap[159]->NotRange.Reserved3 = 0
7752pp_data->cap[159]->NotRange.DataIndex = 72
7753pp_data->cap[159]->NotRange.Reserved4 = 72
7754pp_data->cap[159]->NotButton.HasNull = 0
7755pp_data->cap[159]->NotButton.Reserved4 = 0x000000
7756pp_data->cap[159]->NotButton.LogicalMin = 0
7757pp_data->cap[159]->NotButton.LogicalMax = 127
7758pp_data->cap[159]->NotButton.PhysicalMin = 0
7759pp_data->cap[159]->NotButton.PhysicalMax = 0
7760pp_data->cap[159]->Units = 0
7761pp_data->cap[159]->UnitsExp = 0
7762
7763pp_data->cap[160]->UsagePage = 0xFF01
7764pp_data->cap[160]->ReportID = 0x80
7765pp_data->cap[160]->BitPosition = 0
7766pp_data->cap[160]->BitSize = 8
7767pp_data->cap[160]->ReportCount = 1
7768pp_data->cap[160]->BytePosition = 0x0015
7769pp_data->cap[160]->BitCount = 8
7770pp_data->cap[160]->BitField = 0x02
7771pp_data->cap[160]->NextBytePosition = 0x0016
7772pp_data->cap[160]->LinkCollection = 0x0003
7773pp_data->cap[160]->LinkUsagePage = 0xFF01
7774pp_data->cap[160]->LinkUsage = 0x0080
7775pp_data->cap[160]->IsMultipleItemsForArray = 0
7776pp_data->cap[160]->IsButtonCap = 0
7777pp_data->cap[160]->IsPadding = 0
7778pp_data->cap[160]->IsAbsolute = 1
7779pp_data->cap[160]->IsRange = 0
7780pp_data->cap[160]->IsAlias = 0
7781pp_data->cap[160]->IsStringRange = 0
7782pp_data->cap[160]->IsDesignatorRange = 0
7783pp_data->cap[160]->Reserved1 = 0x000000
7784pp_data->cap[160]->pp_cap->UnknownTokens[0].Token = 0x00
7785pp_data->cap[160]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7786pp_data->cap[160]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7787pp_data->cap[160]->pp_cap->UnknownTokens[1].Token = 0x00
7788pp_data->cap[160]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7789pp_data->cap[160]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7790pp_data->cap[160]->pp_cap->UnknownTokens[2].Token = 0x00
7791pp_data->cap[160]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7792pp_data->cap[160]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7793pp_data->cap[160]->pp_cap->UnknownTokens[3].Token = 0x00
7794pp_data->cap[160]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7795pp_data->cap[160]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7796pp_data->cap[160]->NotRange.Usage = 0x0081
7797pp_data->cap[160]->NotRange.Reserved1 = 0x0081
7798pp_data->cap[160]->NotRange.StringIndex = 0
7799pp_data->cap[160]->NotRange.Reserved2 = 0
7800pp_data->cap[160]->NotRange.DesignatorIndex = 0
7801pp_data->cap[160]->NotRange.Reserved3 = 0
7802pp_data->cap[160]->NotRange.DataIndex = 73
7803pp_data->cap[160]->NotRange.Reserved4 = 73
7804pp_data->cap[160]->NotButton.HasNull = 0
7805pp_data->cap[160]->NotButton.Reserved4 = 0x000000
7806pp_data->cap[160]->NotButton.LogicalMin = 0
7807pp_data->cap[160]->NotButton.LogicalMax = 127
7808pp_data->cap[160]->NotButton.PhysicalMin = 0
7809pp_data->cap[160]->NotButton.PhysicalMax = 0
7810pp_data->cap[160]->Units = 0
7811pp_data->cap[160]->UnitsExp = 0
7812
7813pp_data->cap[161]->UsagePage = 0xFF01
7814pp_data->cap[161]->ReportID = 0x80
7815pp_data->cap[161]->BitPosition = 0
7816pp_data->cap[161]->BitSize = 8
7817pp_data->cap[161]->ReportCount = 1
7818pp_data->cap[161]->BytePosition = 0x0014
7819pp_data->cap[161]->BitCount = 8
7820pp_data->cap[161]->BitField = 0x02
7821pp_data->cap[161]->NextBytePosition = 0x0015
7822pp_data->cap[161]->LinkCollection = 0x0003
7823pp_data->cap[161]->LinkUsagePage = 0xFF01
7824pp_data->cap[161]->LinkUsage = 0x0080
7825pp_data->cap[161]->IsMultipleItemsForArray = 0
7826pp_data->cap[161]->IsButtonCap = 0
7827pp_data->cap[161]->IsPadding = 0
7828pp_data->cap[161]->IsAbsolute = 1
7829pp_data->cap[161]->IsRange = 0
7830pp_data->cap[161]->IsAlias = 0
7831pp_data->cap[161]->IsStringRange = 0
7832pp_data->cap[161]->IsDesignatorRange = 0
7833pp_data->cap[161]->Reserved1 = 0x000000
7834pp_data->cap[161]->pp_cap->UnknownTokens[0].Token = 0x00
7835pp_data->cap[161]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7836pp_data->cap[161]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7837pp_data->cap[161]->pp_cap->UnknownTokens[1].Token = 0x00
7838pp_data->cap[161]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7839pp_data->cap[161]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7840pp_data->cap[161]->pp_cap->UnknownTokens[2].Token = 0x00
7841pp_data->cap[161]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7842pp_data->cap[161]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7843pp_data->cap[161]->pp_cap->UnknownTokens[3].Token = 0x00
7844pp_data->cap[161]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7845pp_data->cap[161]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7846pp_data->cap[161]->NotRange.Usage = 0x0081
7847pp_data->cap[161]->NotRange.Reserved1 = 0x0081
7848pp_data->cap[161]->NotRange.StringIndex = 0
7849pp_data->cap[161]->NotRange.Reserved2 = 0
7850pp_data->cap[161]->NotRange.DesignatorIndex = 0
7851pp_data->cap[161]->NotRange.Reserved3 = 0
7852pp_data->cap[161]->NotRange.DataIndex = 74
7853pp_data->cap[161]->NotRange.Reserved4 = 74
7854pp_data->cap[161]->NotButton.HasNull = 0
7855pp_data->cap[161]->NotButton.Reserved4 = 0x000000
7856pp_data->cap[161]->NotButton.LogicalMin = 0
7857pp_data->cap[161]->NotButton.LogicalMax = 127
7858pp_data->cap[161]->NotButton.PhysicalMin = 0
7859pp_data->cap[161]->NotButton.PhysicalMax = 0
7860pp_data->cap[161]->Units = 0
7861pp_data->cap[161]->UnitsExp = 0
7862
7863pp_data->cap[162]->UsagePage = 0xFF01
7864pp_data->cap[162]->ReportID = 0x80
7865pp_data->cap[162]->BitPosition = 0
7866pp_data->cap[162]->BitSize = 8
7867pp_data->cap[162]->ReportCount = 1
7868pp_data->cap[162]->BytePosition = 0x0013
7869pp_data->cap[162]->BitCount = 8
7870pp_data->cap[162]->BitField = 0x02
7871pp_data->cap[162]->NextBytePosition = 0x0014
7872pp_data->cap[162]->LinkCollection = 0x0003
7873pp_data->cap[162]->LinkUsagePage = 0xFF01
7874pp_data->cap[162]->LinkUsage = 0x0080
7875pp_data->cap[162]->IsMultipleItemsForArray = 0
7876pp_data->cap[162]->IsButtonCap = 0
7877pp_data->cap[162]->IsPadding = 0
7878pp_data->cap[162]->IsAbsolute = 1
7879pp_data->cap[162]->IsRange = 0
7880pp_data->cap[162]->IsAlias = 0
7881pp_data->cap[162]->IsStringRange = 0
7882pp_data->cap[162]->IsDesignatorRange = 0
7883pp_data->cap[162]->Reserved1 = 0x000000
7884pp_data->cap[162]->pp_cap->UnknownTokens[0].Token = 0x00
7885pp_data->cap[162]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7886pp_data->cap[162]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7887pp_data->cap[162]->pp_cap->UnknownTokens[1].Token = 0x00
7888pp_data->cap[162]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7889pp_data->cap[162]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7890pp_data->cap[162]->pp_cap->UnknownTokens[2].Token = 0x00
7891pp_data->cap[162]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7892pp_data->cap[162]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7893pp_data->cap[162]->pp_cap->UnknownTokens[3].Token = 0x00
7894pp_data->cap[162]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7895pp_data->cap[162]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7896pp_data->cap[162]->NotRange.Usage = 0x0081
7897pp_data->cap[162]->NotRange.Reserved1 = 0x0081
7898pp_data->cap[162]->NotRange.StringIndex = 0
7899pp_data->cap[162]->NotRange.Reserved2 = 0
7900pp_data->cap[162]->NotRange.DesignatorIndex = 0
7901pp_data->cap[162]->NotRange.Reserved3 = 0
7902pp_data->cap[162]->NotRange.DataIndex = 75
7903pp_data->cap[162]->NotRange.Reserved4 = 75
7904pp_data->cap[162]->NotButton.HasNull = 0
7905pp_data->cap[162]->NotButton.Reserved4 = 0x000000
7906pp_data->cap[162]->NotButton.LogicalMin = 0
7907pp_data->cap[162]->NotButton.LogicalMax = 127
7908pp_data->cap[162]->NotButton.PhysicalMin = 0
7909pp_data->cap[162]->NotButton.PhysicalMax = 0
7910pp_data->cap[162]->Units = 0
7911pp_data->cap[162]->UnitsExp = 0
7912
7913pp_data->cap[163]->UsagePage = 0xFF01
7914pp_data->cap[163]->ReportID = 0x80
7915pp_data->cap[163]->BitPosition = 0
7916pp_data->cap[163]->BitSize = 8
7917pp_data->cap[163]->ReportCount = 1
7918pp_data->cap[163]->BytePosition = 0x0012
7919pp_data->cap[163]->BitCount = 8
7920pp_data->cap[163]->BitField = 0x02
7921pp_data->cap[163]->NextBytePosition = 0x0013
7922pp_data->cap[163]->LinkCollection = 0x0003
7923pp_data->cap[163]->LinkUsagePage = 0xFF01
7924pp_data->cap[163]->LinkUsage = 0x0080
7925pp_data->cap[163]->IsMultipleItemsForArray = 0
7926pp_data->cap[163]->IsButtonCap = 0
7927pp_data->cap[163]->IsPadding = 0
7928pp_data->cap[163]->IsAbsolute = 1
7929pp_data->cap[163]->IsRange = 0
7930pp_data->cap[163]->IsAlias = 0
7931pp_data->cap[163]->IsStringRange = 0
7932pp_data->cap[163]->IsDesignatorRange = 0
7933pp_data->cap[163]->Reserved1 = 0x000000
7934pp_data->cap[163]->pp_cap->UnknownTokens[0].Token = 0x00
7935pp_data->cap[163]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7936pp_data->cap[163]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7937pp_data->cap[163]->pp_cap->UnknownTokens[1].Token = 0x00
7938pp_data->cap[163]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7939pp_data->cap[163]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7940pp_data->cap[163]->pp_cap->UnknownTokens[2].Token = 0x00
7941pp_data->cap[163]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7942pp_data->cap[163]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7943pp_data->cap[163]->pp_cap->UnknownTokens[3].Token = 0x00
7944pp_data->cap[163]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7945pp_data->cap[163]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7946pp_data->cap[163]->NotRange.Usage = 0x0081
7947pp_data->cap[163]->NotRange.Reserved1 = 0x0081
7948pp_data->cap[163]->NotRange.StringIndex = 0
7949pp_data->cap[163]->NotRange.Reserved2 = 0
7950pp_data->cap[163]->NotRange.DesignatorIndex = 0
7951pp_data->cap[163]->NotRange.Reserved3 = 0
7952pp_data->cap[163]->NotRange.DataIndex = 76
7953pp_data->cap[163]->NotRange.Reserved4 = 76
7954pp_data->cap[163]->NotButton.HasNull = 0
7955pp_data->cap[163]->NotButton.Reserved4 = 0x000000
7956pp_data->cap[163]->NotButton.LogicalMin = 0
7957pp_data->cap[163]->NotButton.LogicalMax = 127
7958pp_data->cap[163]->NotButton.PhysicalMin = 0
7959pp_data->cap[163]->NotButton.PhysicalMax = 0
7960pp_data->cap[163]->Units = 0
7961pp_data->cap[163]->UnitsExp = 0
7962
7963pp_data->cap[164]->UsagePage = 0xFF01
7964pp_data->cap[164]->ReportID = 0x80
7965pp_data->cap[164]->BitPosition = 0
7966pp_data->cap[164]->BitSize = 8
7967pp_data->cap[164]->ReportCount = 1
7968pp_data->cap[164]->BytePosition = 0x0011
7969pp_data->cap[164]->BitCount = 8
7970pp_data->cap[164]->BitField = 0x02
7971pp_data->cap[164]->NextBytePosition = 0x0012
7972pp_data->cap[164]->LinkCollection = 0x0003
7973pp_data->cap[164]->LinkUsagePage = 0xFF01
7974pp_data->cap[164]->LinkUsage = 0x0080
7975pp_data->cap[164]->IsMultipleItemsForArray = 0
7976pp_data->cap[164]->IsButtonCap = 0
7977pp_data->cap[164]->IsPadding = 0
7978pp_data->cap[164]->IsAbsolute = 1
7979pp_data->cap[164]->IsRange = 0
7980pp_data->cap[164]->IsAlias = 0
7981pp_data->cap[164]->IsStringRange = 0
7982pp_data->cap[164]->IsDesignatorRange = 0
7983pp_data->cap[164]->Reserved1 = 0x000000
7984pp_data->cap[164]->pp_cap->UnknownTokens[0].Token = 0x00
7985pp_data->cap[164]->pp_cap->UnknownTokens[0].Reserved = 0x000000
7986pp_data->cap[164]->pp_cap->UnknownTokens[0].BitField = 0x00000000
7987pp_data->cap[164]->pp_cap->UnknownTokens[1].Token = 0x00
7988pp_data->cap[164]->pp_cap->UnknownTokens[1].Reserved = 0x000000
7989pp_data->cap[164]->pp_cap->UnknownTokens[1].BitField = 0x00000000
7990pp_data->cap[164]->pp_cap->UnknownTokens[2].Token = 0x00
7991pp_data->cap[164]->pp_cap->UnknownTokens[2].Reserved = 0x000000
7992pp_data->cap[164]->pp_cap->UnknownTokens[2].BitField = 0x00000000
7993pp_data->cap[164]->pp_cap->UnknownTokens[3].Token = 0x00
7994pp_data->cap[164]->pp_cap->UnknownTokens[3].Reserved = 0x000000
7995pp_data->cap[164]->pp_cap->UnknownTokens[3].BitField = 0x00000000
7996pp_data->cap[164]->NotRange.Usage = 0x0081
7997pp_data->cap[164]->NotRange.Reserved1 = 0x0081
7998pp_data->cap[164]->NotRange.StringIndex = 0
7999pp_data->cap[164]->NotRange.Reserved2 = 0
8000pp_data->cap[164]->NotRange.DesignatorIndex = 0
8001pp_data->cap[164]->NotRange.Reserved3 = 0
8002pp_data->cap[164]->NotRange.DataIndex = 77
8003pp_data->cap[164]->NotRange.Reserved4 = 77
8004pp_data->cap[164]->NotButton.HasNull = 0
8005pp_data->cap[164]->NotButton.Reserved4 = 0x000000
8006pp_data->cap[164]->NotButton.LogicalMin = 0
8007pp_data->cap[164]->NotButton.LogicalMax = 127
8008pp_data->cap[164]->NotButton.PhysicalMin = 0
8009pp_data->cap[164]->NotButton.PhysicalMax = 0
8010pp_data->cap[164]->Units = 0
8011pp_data->cap[164]->UnitsExp = 0
8012
8013pp_data->cap[165]->UsagePage = 0xFF01
8014pp_data->cap[165]->ReportID = 0x80
8015pp_data->cap[165]->BitPosition = 0
8016pp_data->cap[165]->BitSize = 8
8017pp_data->cap[165]->ReportCount = 1
8018pp_data->cap[165]->BytePosition = 0x0010
8019pp_data->cap[165]->BitCount = 8
8020pp_data->cap[165]->BitField = 0x02
8021pp_data->cap[165]->NextBytePosition = 0x0011
8022pp_data->cap[165]->LinkCollection = 0x0003
8023pp_data->cap[165]->LinkUsagePage = 0xFF01
8024pp_data->cap[165]->LinkUsage = 0x0080
8025pp_data->cap[165]->IsMultipleItemsForArray = 0
8026pp_data->cap[165]->IsButtonCap = 0
8027pp_data->cap[165]->IsPadding = 0
8028pp_data->cap[165]->IsAbsolute = 1
8029pp_data->cap[165]->IsRange = 0
8030pp_data->cap[165]->IsAlias = 0
8031pp_data->cap[165]->IsStringRange = 0
8032pp_data->cap[165]->IsDesignatorRange = 0
8033pp_data->cap[165]->Reserved1 = 0x000000
8034pp_data->cap[165]->pp_cap->UnknownTokens[0].Token = 0x00
8035pp_data->cap[165]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8036pp_data->cap[165]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8037pp_data->cap[165]->pp_cap->UnknownTokens[1].Token = 0x00
8038pp_data->cap[165]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8039pp_data->cap[165]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8040pp_data->cap[165]->pp_cap->UnknownTokens[2].Token = 0x00
8041pp_data->cap[165]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8042pp_data->cap[165]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8043pp_data->cap[165]->pp_cap->UnknownTokens[3].Token = 0x00
8044pp_data->cap[165]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8045pp_data->cap[165]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8046pp_data->cap[165]->NotRange.Usage = 0x0081
8047pp_data->cap[165]->NotRange.Reserved1 = 0x0081
8048pp_data->cap[165]->NotRange.StringIndex = 0
8049pp_data->cap[165]->NotRange.Reserved2 = 0
8050pp_data->cap[165]->NotRange.DesignatorIndex = 0
8051pp_data->cap[165]->NotRange.Reserved3 = 0
8052pp_data->cap[165]->NotRange.DataIndex = 78
8053pp_data->cap[165]->NotRange.Reserved4 = 78
8054pp_data->cap[165]->NotButton.HasNull = 0
8055pp_data->cap[165]->NotButton.Reserved4 = 0x000000
8056pp_data->cap[165]->NotButton.LogicalMin = 0
8057pp_data->cap[165]->NotButton.LogicalMax = 127
8058pp_data->cap[165]->NotButton.PhysicalMin = 0
8059pp_data->cap[165]->NotButton.PhysicalMax = 0
8060pp_data->cap[165]->Units = 0
8061pp_data->cap[165]->UnitsExp = 0
8062
8063pp_data->cap[166]->UsagePage = 0xFF01
8064pp_data->cap[166]->ReportID = 0x80
8065pp_data->cap[166]->BitPosition = 0
8066pp_data->cap[166]->BitSize = 8
8067pp_data->cap[166]->ReportCount = 1
8068pp_data->cap[166]->BytePosition = 0x000F
8069pp_data->cap[166]->BitCount = 8
8070pp_data->cap[166]->BitField = 0x02
8071pp_data->cap[166]->NextBytePosition = 0x0010
8072pp_data->cap[166]->LinkCollection = 0x0003
8073pp_data->cap[166]->LinkUsagePage = 0xFF01
8074pp_data->cap[166]->LinkUsage = 0x0080
8075pp_data->cap[166]->IsMultipleItemsForArray = 0
8076pp_data->cap[166]->IsButtonCap = 0
8077pp_data->cap[166]->IsPadding = 0
8078pp_data->cap[166]->IsAbsolute = 1
8079pp_data->cap[166]->IsRange = 0
8080pp_data->cap[166]->IsAlias = 0
8081pp_data->cap[166]->IsStringRange = 0
8082pp_data->cap[166]->IsDesignatorRange = 0
8083pp_data->cap[166]->Reserved1 = 0x000000
8084pp_data->cap[166]->pp_cap->UnknownTokens[0].Token = 0x00
8085pp_data->cap[166]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8086pp_data->cap[166]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8087pp_data->cap[166]->pp_cap->UnknownTokens[1].Token = 0x00
8088pp_data->cap[166]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8089pp_data->cap[166]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8090pp_data->cap[166]->pp_cap->UnknownTokens[2].Token = 0x00
8091pp_data->cap[166]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8092pp_data->cap[166]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8093pp_data->cap[166]->pp_cap->UnknownTokens[3].Token = 0x00
8094pp_data->cap[166]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8095pp_data->cap[166]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8096pp_data->cap[166]->NotRange.Usage = 0x0081
8097pp_data->cap[166]->NotRange.Reserved1 = 0x0081
8098pp_data->cap[166]->NotRange.StringIndex = 0
8099pp_data->cap[166]->NotRange.Reserved2 = 0
8100pp_data->cap[166]->NotRange.DesignatorIndex = 0
8101pp_data->cap[166]->NotRange.Reserved3 = 0
8102pp_data->cap[166]->NotRange.DataIndex = 79
8103pp_data->cap[166]->NotRange.Reserved4 = 79
8104pp_data->cap[166]->NotButton.HasNull = 0
8105pp_data->cap[166]->NotButton.Reserved4 = 0x000000
8106pp_data->cap[166]->NotButton.LogicalMin = 0
8107pp_data->cap[166]->NotButton.LogicalMax = 127
8108pp_data->cap[166]->NotButton.PhysicalMin = 0
8109pp_data->cap[166]->NotButton.PhysicalMax = 0
8110pp_data->cap[166]->Units = 0
8111pp_data->cap[166]->UnitsExp = 0
8112
8113pp_data->cap[167]->UsagePage = 0xFF01
8114pp_data->cap[167]->ReportID = 0x80
8115pp_data->cap[167]->BitPosition = 0
8116pp_data->cap[167]->BitSize = 8
8117pp_data->cap[167]->ReportCount = 1
8118pp_data->cap[167]->BytePosition = 0x000E
8119pp_data->cap[167]->BitCount = 8
8120pp_data->cap[167]->BitField = 0x02
8121pp_data->cap[167]->NextBytePosition = 0x000F
8122pp_data->cap[167]->LinkCollection = 0x0003
8123pp_data->cap[167]->LinkUsagePage = 0xFF01
8124pp_data->cap[167]->LinkUsage = 0x0080
8125pp_data->cap[167]->IsMultipleItemsForArray = 0
8126pp_data->cap[167]->IsButtonCap = 0
8127pp_data->cap[167]->IsPadding = 0
8128pp_data->cap[167]->IsAbsolute = 1
8129pp_data->cap[167]->IsRange = 0
8130pp_data->cap[167]->IsAlias = 0
8131pp_data->cap[167]->IsStringRange = 0
8132pp_data->cap[167]->IsDesignatorRange = 0
8133pp_data->cap[167]->Reserved1 = 0x000000
8134pp_data->cap[167]->pp_cap->UnknownTokens[0].Token = 0x00
8135pp_data->cap[167]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8136pp_data->cap[167]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8137pp_data->cap[167]->pp_cap->UnknownTokens[1].Token = 0x00
8138pp_data->cap[167]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8139pp_data->cap[167]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8140pp_data->cap[167]->pp_cap->UnknownTokens[2].Token = 0x00
8141pp_data->cap[167]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8142pp_data->cap[167]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8143pp_data->cap[167]->pp_cap->UnknownTokens[3].Token = 0x00
8144pp_data->cap[167]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8145pp_data->cap[167]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8146pp_data->cap[167]->NotRange.Usage = 0x0081
8147pp_data->cap[167]->NotRange.Reserved1 = 0x0081
8148pp_data->cap[167]->NotRange.StringIndex = 0
8149pp_data->cap[167]->NotRange.Reserved2 = 0
8150pp_data->cap[167]->NotRange.DesignatorIndex = 0
8151pp_data->cap[167]->NotRange.Reserved3 = 0
8152pp_data->cap[167]->NotRange.DataIndex = 80
8153pp_data->cap[167]->NotRange.Reserved4 = 80
8154pp_data->cap[167]->NotButton.HasNull = 0
8155pp_data->cap[167]->NotButton.Reserved4 = 0x000000
8156pp_data->cap[167]->NotButton.LogicalMin = 0
8157pp_data->cap[167]->NotButton.LogicalMax = 127
8158pp_data->cap[167]->NotButton.PhysicalMin = 0
8159pp_data->cap[167]->NotButton.PhysicalMax = 0
8160pp_data->cap[167]->Units = 0
8161pp_data->cap[167]->UnitsExp = 0
8162
8163pp_data->cap[168]->UsagePage = 0xFF01
8164pp_data->cap[168]->ReportID = 0x80
8165pp_data->cap[168]->BitPosition = 0
8166pp_data->cap[168]->BitSize = 8
8167pp_data->cap[168]->ReportCount = 1
8168pp_data->cap[168]->BytePosition = 0x000D
8169pp_data->cap[168]->BitCount = 8
8170pp_data->cap[168]->BitField = 0x02
8171pp_data->cap[168]->NextBytePosition = 0x000E
8172pp_data->cap[168]->LinkCollection = 0x0003
8173pp_data->cap[168]->LinkUsagePage = 0xFF01
8174pp_data->cap[168]->LinkUsage = 0x0080
8175pp_data->cap[168]->IsMultipleItemsForArray = 0
8176pp_data->cap[168]->IsButtonCap = 0
8177pp_data->cap[168]->IsPadding = 0
8178pp_data->cap[168]->IsAbsolute = 1
8179pp_data->cap[168]->IsRange = 0
8180pp_data->cap[168]->IsAlias = 0
8181pp_data->cap[168]->IsStringRange = 0
8182pp_data->cap[168]->IsDesignatorRange = 0
8183pp_data->cap[168]->Reserved1 = 0x000000
8184pp_data->cap[168]->pp_cap->UnknownTokens[0].Token = 0x00
8185pp_data->cap[168]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8186pp_data->cap[168]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8187pp_data->cap[168]->pp_cap->UnknownTokens[1].Token = 0x00
8188pp_data->cap[168]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8189pp_data->cap[168]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8190pp_data->cap[168]->pp_cap->UnknownTokens[2].Token = 0x00
8191pp_data->cap[168]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8192pp_data->cap[168]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8193pp_data->cap[168]->pp_cap->UnknownTokens[3].Token = 0x00
8194pp_data->cap[168]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8195pp_data->cap[168]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8196pp_data->cap[168]->NotRange.Usage = 0x0081
8197pp_data->cap[168]->NotRange.Reserved1 = 0x0081
8198pp_data->cap[168]->NotRange.StringIndex = 0
8199pp_data->cap[168]->NotRange.Reserved2 = 0
8200pp_data->cap[168]->NotRange.DesignatorIndex = 0
8201pp_data->cap[168]->NotRange.Reserved3 = 0
8202pp_data->cap[168]->NotRange.DataIndex = 81
8203pp_data->cap[168]->NotRange.Reserved4 = 81
8204pp_data->cap[168]->NotButton.HasNull = 0
8205pp_data->cap[168]->NotButton.Reserved4 = 0x000000
8206pp_data->cap[168]->NotButton.LogicalMin = 0
8207pp_data->cap[168]->NotButton.LogicalMax = 127
8208pp_data->cap[168]->NotButton.PhysicalMin = 0
8209pp_data->cap[168]->NotButton.PhysicalMax = 0
8210pp_data->cap[168]->Units = 0
8211pp_data->cap[168]->UnitsExp = 0
8212
8213pp_data->cap[169]->UsagePage = 0xFF01
8214pp_data->cap[169]->ReportID = 0x80
8215pp_data->cap[169]->BitPosition = 0
8216pp_data->cap[169]->BitSize = 8
8217pp_data->cap[169]->ReportCount = 1
8218pp_data->cap[169]->BytePosition = 0x000C
8219pp_data->cap[169]->BitCount = 8
8220pp_data->cap[169]->BitField = 0x02
8221pp_data->cap[169]->NextBytePosition = 0x000D
8222pp_data->cap[169]->LinkCollection = 0x0003
8223pp_data->cap[169]->LinkUsagePage = 0xFF01
8224pp_data->cap[169]->LinkUsage = 0x0080
8225pp_data->cap[169]->IsMultipleItemsForArray = 0
8226pp_data->cap[169]->IsButtonCap = 0
8227pp_data->cap[169]->IsPadding = 0
8228pp_data->cap[169]->IsAbsolute = 1
8229pp_data->cap[169]->IsRange = 0
8230pp_data->cap[169]->IsAlias = 0
8231pp_data->cap[169]->IsStringRange = 0
8232pp_data->cap[169]->IsDesignatorRange = 0
8233pp_data->cap[169]->Reserved1 = 0x000000
8234pp_data->cap[169]->pp_cap->UnknownTokens[0].Token = 0x00
8235pp_data->cap[169]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8236pp_data->cap[169]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8237pp_data->cap[169]->pp_cap->UnknownTokens[1].Token = 0x00
8238pp_data->cap[169]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8239pp_data->cap[169]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8240pp_data->cap[169]->pp_cap->UnknownTokens[2].Token = 0x00
8241pp_data->cap[169]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8242pp_data->cap[169]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8243pp_data->cap[169]->pp_cap->UnknownTokens[3].Token = 0x00
8244pp_data->cap[169]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8245pp_data->cap[169]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8246pp_data->cap[169]->NotRange.Usage = 0x0081
8247pp_data->cap[169]->NotRange.Reserved1 = 0x0081
8248pp_data->cap[169]->NotRange.StringIndex = 0
8249pp_data->cap[169]->NotRange.Reserved2 = 0
8250pp_data->cap[169]->NotRange.DesignatorIndex = 0
8251pp_data->cap[169]->NotRange.Reserved3 = 0
8252pp_data->cap[169]->NotRange.DataIndex = 82
8253pp_data->cap[169]->NotRange.Reserved4 = 82
8254pp_data->cap[169]->NotButton.HasNull = 0
8255pp_data->cap[169]->NotButton.Reserved4 = 0x000000
8256pp_data->cap[169]->NotButton.LogicalMin = 0
8257pp_data->cap[169]->NotButton.LogicalMax = 127
8258pp_data->cap[169]->NotButton.PhysicalMin = 0
8259pp_data->cap[169]->NotButton.PhysicalMax = 0
8260pp_data->cap[169]->Units = 0
8261pp_data->cap[169]->UnitsExp = 0
8262
8263pp_data->cap[170]->UsagePage = 0xFF01
8264pp_data->cap[170]->ReportID = 0x80
8265pp_data->cap[170]->BitPosition = 0
8266pp_data->cap[170]->BitSize = 8
8267pp_data->cap[170]->ReportCount = 1
8268pp_data->cap[170]->BytePosition = 0x000B
8269pp_data->cap[170]->BitCount = 8
8270pp_data->cap[170]->BitField = 0x02
8271pp_data->cap[170]->NextBytePosition = 0x000C
8272pp_data->cap[170]->LinkCollection = 0x0003
8273pp_data->cap[170]->LinkUsagePage = 0xFF01
8274pp_data->cap[170]->LinkUsage = 0x0080
8275pp_data->cap[170]->IsMultipleItemsForArray = 0
8276pp_data->cap[170]->IsButtonCap = 0
8277pp_data->cap[170]->IsPadding = 0
8278pp_data->cap[170]->IsAbsolute = 1
8279pp_data->cap[170]->IsRange = 0
8280pp_data->cap[170]->IsAlias = 0
8281pp_data->cap[170]->IsStringRange = 0
8282pp_data->cap[170]->IsDesignatorRange = 0
8283pp_data->cap[170]->Reserved1 = 0x000000
8284pp_data->cap[170]->pp_cap->UnknownTokens[0].Token = 0x00
8285pp_data->cap[170]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8286pp_data->cap[170]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8287pp_data->cap[170]->pp_cap->UnknownTokens[1].Token = 0x00
8288pp_data->cap[170]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8289pp_data->cap[170]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8290pp_data->cap[170]->pp_cap->UnknownTokens[2].Token = 0x00
8291pp_data->cap[170]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8292pp_data->cap[170]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8293pp_data->cap[170]->pp_cap->UnknownTokens[3].Token = 0x00
8294pp_data->cap[170]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8295pp_data->cap[170]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8296pp_data->cap[170]->NotRange.Usage = 0x0081
8297pp_data->cap[170]->NotRange.Reserved1 = 0x0081
8298pp_data->cap[170]->NotRange.StringIndex = 0
8299pp_data->cap[170]->NotRange.Reserved2 = 0
8300pp_data->cap[170]->NotRange.DesignatorIndex = 0
8301pp_data->cap[170]->NotRange.Reserved3 = 0
8302pp_data->cap[170]->NotRange.DataIndex = 83
8303pp_data->cap[170]->NotRange.Reserved4 = 83
8304pp_data->cap[170]->NotButton.HasNull = 0
8305pp_data->cap[170]->NotButton.Reserved4 = 0x000000
8306pp_data->cap[170]->NotButton.LogicalMin = 0
8307pp_data->cap[170]->NotButton.LogicalMax = 127
8308pp_data->cap[170]->NotButton.PhysicalMin = 0
8309pp_data->cap[170]->NotButton.PhysicalMax = 0
8310pp_data->cap[170]->Units = 0
8311pp_data->cap[170]->UnitsExp = 0
8312
8313pp_data->cap[171]->UsagePage = 0xFF01
8314pp_data->cap[171]->ReportID = 0x80
8315pp_data->cap[171]->BitPosition = 0
8316pp_data->cap[171]->BitSize = 8
8317pp_data->cap[171]->ReportCount = 1
8318pp_data->cap[171]->BytePosition = 0x000A
8319pp_data->cap[171]->BitCount = 8
8320pp_data->cap[171]->BitField = 0x02
8321pp_data->cap[171]->NextBytePosition = 0x000B
8322pp_data->cap[171]->LinkCollection = 0x0003
8323pp_data->cap[171]->LinkUsagePage = 0xFF01
8324pp_data->cap[171]->LinkUsage = 0x0080
8325pp_data->cap[171]->IsMultipleItemsForArray = 0
8326pp_data->cap[171]->IsButtonCap = 0
8327pp_data->cap[171]->IsPadding = 0
8328pp_data->cap[171]->IsAbsolute = 1
8329pp_data->cap[171]->IsRange = 0
8330pp_data->cap[171]->IsAlias = 0
8331pp_data->cap[171]->IsStringRange = 0
8332pp_data->cap[171]->IsDesignatorRange = 0
8333pp_data->cap[171]->Reserved1 = 0x000000
8334pp_data->cap[171]->pp_cap->UnknownTokens[0].Token = 0x00
8335pp_data->cap[171]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8336pp_data->cap[171]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8337pp_data->cap[171]->pp_cap->UnknownTokens[1].Token = 0x00
8338pp_data->cap[171]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8339pp_data->cap[171]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8340pp_data->cap[171]->pp_cap->UnknownTokens[2].Token = 0x00
8341pp_data->cap[171]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8342pp_data->cap[171]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8343pp_data->cap[171]->pp_cap->UnknownTokens[3].Token = 0x00
8344pp_data->cap[171]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8345pp_data->cap[171]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8346pp_data->cap[171]->NotRange.Usage = 0x0081
8347pp_data->cap[171]->NotRange.Reserved1 = 0x0081
8348pp_data->cap[171]->NotRange.StringIndex = 0
8349pp_data->cap[171]->NotRange.Reserved2 = 0
8350pp_data->cap[171]->NotRange.DesignatorIndex = 0
8351pp_data->cap[171]->NotRange.Reserved3 = 0
8352pp_data->cap[171]->NotRange.DataIndex = 84
8353pp_data->cap[171]->NotRange.Reserved4 = 84
8354pp_data->cap[171]->NotButton.HasNull = 0
8355pp_data->cap[171]->NotButton.Reserved4 = 0x000000
8356pp_data->cap[171]->NotButton.LogicalMin = 0
8357pp_data->cap[171]->NotButton.LogicalMax = 127
8358pp_data->cap[171]->NotButton.PhysicalMin = 0
8359pp_data->cap[171]->NotButton.PhysicalMax = 0
8360pp_data->cap[171]->Units = 0
8361pp_data->cap[171]->UnitsExp = 0
8362
8363pp_data->cap[172]->UsagePage = 0xFF01
8364pp_data->cap[172]->ReportID = 0x80
8365pp_data->cap[172]->BitPosition = 0
8366pp_data->cap[172]->BitSize = 8
8367pp_data->cap[172]->ReportCount = 1
8368pp_data->cap[172]->BytePosition = 0x0009
8369pp_data->cap[172]->BitCount = 8
8370pp_data->cap[172]->BitField = 0x02
8371pp_data->cap[172]->NextBytePosition = 0x000A
8372pp_data->cap[172]->LinkCollection = 0x0003
8373pp_data->cap[172]->LinkUsagePage = 0xFF01
8374pp_data->cap[172]->LinkUsage = 0x0080
8375pp_data->cap[172]->IsMultipleItemsForArray = 0
8376pp_data->cap[172]->IsButtonCap = 0
8377pp_data->cap[172]->IsPadding = 0
8378pp_data->cap[172]->IsAbsolute = 1
8379pp_data->cap[172]->IsRange = 0
8380pp_data->cap[172]->IsAlias = 0
8381pp_data->cap[172]->IsStringRange = 0
8382pp_data->cap[172]->IsDesignatorRange = 0
8383pp_data->cap[172]->Reserved1 = 0x000000
8384pp_data->cap[172]->pp_cap->UnknownTokens[0].Token = 0x00
8385pp_data->cap[172]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8386pp_data->cap[172]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8387pp_data->cap[172]->pp_cap->UnknownTokens[1].Token = 0x00
8388pp_data->cap[172]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8389pp_data->cap[172]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8390pp_data->cap[172]->pp_cap->UnknownTokens[2].Token = 0x00
8391pp_data->cap[172]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8392pp_data->cap[172]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8393pp_data->cap[172]->pp_cap->UnknownTokens[3].Token = 0x00
8394pp_data->cap[172]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8395pp_data->cap[172]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8396pp_data->cap[172]->NotRange.Usage = 0x0081
8397pp_data->cap[172]->NotRange.Reserved1 = 0x0081
8398pp_data->cap[172]->NotRange.StringIndex = 0
8399pp_data->cap[172]->NotRange.Reserved2 = 0
8400pp_data->cap[172]->NotRange.DesignatorIndex = 0
8401pp_data->cap[172]->NotRange.Reserved3 = 0
8402pp_data->cap[172]->NotRange.DataIndex = 85
8403pp_data->cap[172]->NotRange.Reserved4 = 85
8404pp_data->cap[172]->NotButton.HasNull = 0
8405pp_data->cap[172]->NotButton.Reserved4 = 0x000000
8406pp_data->cap[172]->NotButton.LogicalMin = 0
8407pp_data->cap[172]->NotButton.LogicalMax = 127
8408pp_data->cap[172]->NotButton.PhysicalMin = 0
8409pp_data->cap[172]->NotButton.PhysicalMax = 0
8410pp_data->cap[172]->Units = 0
8411pp_data->cap[172]->UnitsExp = 0
8412
8413pp_data->cap[173]->UsagePage = 0xFF01
8414pp_data->cap[173]->ReportID = 0x80
8415pp_data->cap[173]->BitPosition = 0
8416pp_data->cap[173]->BitSize = 8
8417pp_data->cap[173]->ReportCount = 1
8418pp_data->cap[173]->BytePosition = 0x0008
8419pp_data->cap[173]->BitCount = 8
8420pp_data->cap[173]->BitField = 0x02
8421pp_data->cap[173]->NextBytePosition = 0x0009
8422pp_data->cap[173]->LinkCollection = 0x0003
8423pp_data->cap[173]->LinkUsagePage = 0xFF01
8424pp_data->cap[173]->LinkUsage = 0x0080
8425pp_data->cap[173]->IsMultipleItemsForArray = 0
8426pp_data->cap[173]->IsButtonCap = 0
8427pp_data->cap[173]->IsPadding = 0
8428pp_data->cap[173]->IsAbsolute = 1
8429pp_data->cap[173]->IsRange = 0
8430pp_data->cap[173]->IsAlias = 0
8431pp_data->cap[173]->IsStringRange = 0
8432pp_data->cap[173]->IsDesignatorRange = 0
8433pp_data->cap[173]->Reserved1 = 0x000000
8434pp_data->cap[173]->pp_cap->UnknownTokens[0].Token = 0x00
8435pp_data->cap[173]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8436pp_data->cap[173]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8437pp_data->cap[173]->pp_cap->UnknownTokens[1].Token = 0x00
8438pp_data->cap[173]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8439pp_data->cap[173]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8440pp_data->cap[173]->pp_cap->UnknownTokens[2].Token = 0x00
8441pp_data->cap[173]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8442pp_data->cap[173]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8443pp_data->cap[173]->pp_cap->UnknownTokens[3].Token = 0x00
8444pp_data->cap[173]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8445pp_data->cap[173]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8446pp_data->cap[173]->NotRange.Usage = 0x0081
8447pp_data->cap[173]->NotRange.Reserved1 = 0x0081
8448pp_data->cap[173]->NotRange.StringIndex = 0
8449pp_data->cap[173]->NotRange.Reserved2 = 0
8450pp_data->cap[173]->NotRange.DesignatorIndex = 0
8451pp_data->cap[173]->NotRange.Reserved3 = 0
8452pp_data->cap[173]->NotRange.DataIndex = 86
8453pp_data->cap[173]->NotRange.Reserved4 = 86
8454pp_data->cap[173]->NotButton.HasNull = 0
8455pp_data->cap[173]->NotButton.Reserved4 = 0x000000
8456pp_data->cap[173]->NotButton.LogicalMin = 0
8457pp_data->cap[173]->NotButton.LogicalMax = 127
8458pp_data->cap[173]->NotButton.PhysicalMin = 0
8459pp_data->cap[173]->NotButton.PhysicalMax = 0
8460pp_data->cap[173]->Units = 0
8461pp_data->cap[173]->UnitsExp = 0
8462
8463pp_data->cap[174]->UsagePage = 0xFF01
8464pp_data->cap[174]->ReportID = 0x80
8465pp_data->cap[174]->BitPosition = 0
8466pp_data->cap[174]->BitSize = 8
8467pp_data->cap[174]->ReportCount = 1
8468pp_data->cap[174]->BytePosition = 0x0007
8469pp_data->cap[174]->BitCount = 8
8470pp_data->cap[174]->BitField = 0x02
8471pp_data->cap[174]->NextBytePosition = 0x0008
8472pp_data->cap[174]->LinkCollection = 0x0003
8473pp_data->cap[174]->LinkUsagePage = 0xFF01
8474pp_data->cap[174]->LinkUsage = 0x0080
8475pp_data->cap[174]->IsMultipleItemsForArray = 0
8476pp_data->cap[174]->IsButtonCap = 0
8477pp_data->cap[174]->IsPadding = 0
8478pp_data->cap[174]->IsAbsolute = 1
8479pp_data->cap[174]->IsRange = 0
8480pp_data->cap[174]->IsAlias = 0
8481pp_data->cap[174]->IsStringRange = 0
8482pp_data->cap[174]->IsDesignatorRange = 0
8483pp_data->cap[174]->Reserved1 = 0x000000
8484pp_data->cap[174]->pp_cap->UnknownTokens[0].Token = 0x00
8485pp_data->cap[174]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8486pp_data->cap[174]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8487pp_data->cap[174]->pp_cap->UnknownTokens[1].Token = 0x00
8488pp_data->cap[174]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8489pp_data->cap[174]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8490pp_data->cap[174]->pp_cap->UnknownTokens[2].Token = 0x00
8491pp_data->cap[174]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8492pp_data->cap[174]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8493pp_data->cap[174]->pp_cap->UnknownTokens[3].Token = 0x00
8494pp_data->cap[174]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8495pp_data->cap[174]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8496pp_data->cap[174]->NotRange.Usage = 0x0081
8497pp_data->cap[174]->NotRange.Reserved1 = 0x0081
8498pp_data->cap[174]->NotRange.StringIndex = 0
8499pp_data->cap[174]->NotRange.Reserved2 = 0
8500pp_data->cap[174]->NotRange.DesignatorIndex = 0
8501pp_data->cap[174]->NotRange.Reserved3 = 0
8502pp_data->cap[174]->NotRange.DataIndex = 87
8503pp_data->cap[174]->NotRange.Reserved4 = 87
8504pp_data->cap[174]->NotButton.HasNull = 0
8505pp_data->cap[174]->NotButton.Reserved4 = 0x000000
8506pp_data->cap[174]->NotButton.LogicalMin = 0
8507pp_data->cap[174]->NotButton.LogicalMax = 127
8508pp_data->cap[174]->NotButton.PhysicalMin = 0
8509pp_data->cap[174]->NotButton.PhysicalMax = 0
8510pp_data->cap[174]->Units = 0
8511pp_data->cap[174]->UnitsExp = 0
8512
8513pp_data->cap[175]->UsagePage = 0xFF01
8514pp_data->cap[175]->ReportID = 0x80
8515pp_data->cap[175]->BitPosition = 0
8516pp_data->cap[175]->BitSize = 8
8517pp_data->cap[175]->ReportCount = 1
8518pp_data->cap[175]->BytePosition = 0x0006
8519pp_data->cap[175]->BitCount = 8
8520pp_data->cap[175]->BitField = 0x02
8521pp_data->cap[175]->NextBytePosition = 0x0007
8522pp_data->cap[175]->LinkCollection = 0x0003
8523pp_data->cap[175]->LinkUsagePage = 0xFF01
8524pp_data->cap[175]->LinkUsage = 0x0080
8525pp_data->cap[175]->IsMultipleItemsForArray = 0
8526pp_data->cap[175]->IsButtonCap = 0
8527pp_data->cap[175]->IsPadding = 0
8528pp_data->cap[175]->IsAbsolute = 1
8529pp_data->cap[175]->IsRange = 0
8530pp_data->cap[175]->IsAlias = 0
8531pp_data->cap[175]->IsStringRange = 0
8532pp_data->cap[175]->IsDesignatorRange = 0
8533pp_data->cap[175]->Reserved1 = 0x000000
8534pp_data->cap[175]->pp_cap->UnknownTokens[0].Token = 0x00
8535pp_data->cap[175]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8536pp_data->cap[175]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8537pp_data->cap[175]->pp_cap->UnknownTokens[1].Token = 0x00
8538pp_data->cap[175]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8539pp_data->cap[175]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8540pp_data->cap[175]->pp_cap->UnknownTokens[2].Token = 0x00
8541pp_data->cap[175]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8542pp_data->cap[175]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8543pp_data->cap[175]->pp_cap->UnknownTokens[3].Token = 0x00
8544pp_data->cap[175]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8545pp_data->cap[175]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8546pp_data->cap[175]->NotRange.Usage = 0x0081
8547pp_data->cap[175]->NotRange.Reserved1 = 0x0081
8548pp_data->cap[175]->NotRange.StringIndex = 0
8549pp_data->cap[175]->NotRange.Reserved2 = 0
8550pp_data->cap[175]->NotRange.DesignatorIndex = 0
8551pp_data->cap[175]->NotRange.Reserved3 = 0
8552pp_data->cap[175]->NotRange.DataIndex = 88
8553pp_data->cap[175]->NotRange.Reserved4 = 88
8554pp_data->cap[175]->NotButton.HasNull = 0
8555pp_data->cap[175]->NotButton.Reserved4 = 0x000000
8556pp_data->cap[175]->NotButton.LogicalMin = 0
8557pp_data->cap[175]->NotButton.LogicalMax = 127
8558pp_data->cap[175]->NotButton.PhysicalMin = 0
8559pp_data->cap[175]->NotButton.PhysicalMax = 0
8560pp_data->cap[175]->Units = 0
8561pp_data->cap[175]->UnitsExp = 0
8562
8563pp_data->cap[176]->UsagePage = 0xFF01
8564pp_data->cap[176]->ReportID = 0x80
8565pp_data->cap[176]->BitPosition = 0
8566pp_data->cap[176]->BitSize = 8
8567pp_data->cap[176]->ReportCount = 1
8568pp_data->cap[176]->BytePosition = 0x0005
8569pp_data->cap[176]->BitCount = 8
8570pp_data->cap[176]->BitField = 0x02
8571pp_data->cap[176]->NextBytePosition = 0x0006
8572pp_data->cap[176]->LinkCollection = 0x0003
8573pp_data->cap[176]->LinkUsagePage = 0xFF01
8574pp_data->cap[176]->LinkUsage = 0x0080
8575pp_data->cap[176]->IsMultipleItemsForArray = 0
8576pp_data->cap[176]->IsButtonCap = 0
8577pp_data->cap[176]->IsPadding = 0
8578pp_data->cap[176]->IsAbsolute = 1
8579pp_data->cap[176]->IsRange = 0
8580pp_data->cap[176]->IsAlias = 0
8581pp_data->cap[176]->IsStringRange = 0
8582pp_data->cap[176]->IsDesignatorRange = 0
8583pp_data->cap[176]->Reserved1 = 0x000000
8584pp_data->cap[176]->pp_cap->UnknownTokens[0].Token = 0x00
8585pp_data->cap[176]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8586pp_data->cap[176]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8587pp_data->cap[176]->pp_cap->UnknownTokens[1].Token = 0x00
8588pp_data->cap[176]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8589pp_data->cap[176]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8590pp_data->cap[176]->pp_cap->UnknownTokens[2].Token = 0x00
8591pp_data->cap[176]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8592pp_data->cap[176]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8593pp_data->cap[176]->pp_cap->UnknownTokens[3].Token = 0x00
8594pp_data->cap[176]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8595pp_data->cap[176]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8596pp_data->cap[176]->NotRange.Usage = 0x0081
8597pp_data->cap[176]->NotRange.Reserved1 = 0x0081
8598pp_data->cap[176]->NotRange.StringIndex = 0
8599pp_data->cap[176]->NotRange.Reserved2 = 0
8600pp_data->cap[176]->NotRange.DesignatorIndex = 0
8601pp_data->cap[176]->NotRange.Reserved3 = 0
8602pp_data->cap[176]->NotRange.DataIndex = 89
8603pp_data->cap[176]->NotRange.Reserved4 = 89
8604pp_data->cap[176]->NotButton.HasNull = 0
8605pp_data->cap[176]->NotButton.Reserved4 = 0x000000
8606pp_data->cap[176]->NotButton.LogicalMin = 0
8607pp_data->cap[176]->NotButton.LogicalMax = 127
8608pp_data->cap[176]->NotButton.PhysicalMin = 0
8609pp_data->cap[176]->NotButton.PhysicalMax = 0
8610pp_data->cap[176]->Units = 0
8611pp_data->cap[176]->UnitsExp = 0
8612
8613pp_data->cap[177]->UsagePage = 0xFF01
8614pp_data->cap[177]->ReportID = 0x80
8615pp_data->cap[177]->BitPosition = 0
8616pp_data->cap[177]->BitSize = 8
8617pp_data->cap[177]->ReportCount = 1
8618pp_data->cap[177]->BytePosition = 0x0004
8619pp_data->cap[177]->BitCount = 8
8620pp_data->cap[177]->BitField = 0x02
8621pp_data->cap[177]->NextBytePosition = 0x0005
8622pp_data->cap[177]->LinkCollection = 0x0003
8623pp_data->cap[177]->LinkUsagePage = 0xFF01
8624pp_data->cap[177]->LinkUsage = 0x0080
8625pp_data->cap[177]->IsMultipleItemsForArray = 0
8626pp_data->cap[177]->IsButtonCap = 0
8627pp_data->cap[177]->IsPadding = 0
8628pp_data->cap[177]->IsAbsolute = 1
8629pp_data->cap[177]->IsRange = 0
8630pp_data->cap[177]->IsAlias = 0
8631pp_data->cap[177]->IsStringRange = 0
8632pp_data->cap[177]->IsDesignatorRange = 0
8633pp_data->cap[177]->Reserved1 = 0x000000
8634pp_data->cap[177]->pp_cap->UnknownTokens[0].Token = 0x00
8635pp_data->cap[177]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8636pp_data->cap[177]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8637pp_data->cap[177]->pp_cap->UnknownTokens[1].Token = 0x00
8638pp_data->cap[177]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8639pp_data->cap[177]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8640pp_data->cap[177]->pp_cap->UnknownTokens[2].Token = 0x00
8641pp_data->cap[177]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8642pp_data->cap[177]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8643pp_data->cap[177]->pp_cap->UnknownTokens[3].Token = 0x00
8644pp_data->cap[177]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8645pp_data->cap[177]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8646pp_data->cap[177]->NotRange.Usage = 0x0081
8647pp_data->cap[177]->NotRange.Reserved1 = 0x0081
8648pp_data->cap[177]->NotRange.StringIndex = 0
8649pp_data->cap[177]->NotRange.Reserved2 = 0
8650pp_data->cap[177]->NotRange.DesignatorIndex = 0
8651pp_data->cap[177]->NotRange.Reserved3 = 0
8652pp_data->cap[177]->NotRange.DataIndex = 90
8653pp_data->cap[177]->NotRange.Reserved4 = 90
8654pp_data->cap[177]->NotButton.HasNull = 0
8655pp_data->cap[177]->NotButton.Reserved4 = 0x000000
8656pp_data->cap[177]->NotButton.LogicalMin = 0
8657pp_data->cap[177]->NotButton.LogicalMax = 127
8658pp_data->cap[177]->NotButton.PhysicalMin = 0
8659pp_data->cap[177]->NotButton.PhysicalMax = 0
8660pp_data->cap[177]->Units = 0
8661pp_data->cap[177]->UnitsExp = 0
8662
8663pp_data->cap[178]->UsagePage = 0xFF01
8664pp_data->cap[178]->ReportID = 0x80
8665pp_data->cap[178]->BitPosition = 0
8666pp_data->cap[178]->BitSize = 8
8667pp_data->cap[178]->ReportCount = 1
8668pp_data->cap[178]->BytePosition = 0x0003
8669pp_data->cap[178]->BitCount = 8
8670pp_data->cap[178]->BitField = 0x02
8671pp_data->cap[178]->NextBytePosition = 0x0004
8672pp_data->cap[178]->LinkCollection = 0x0003
8673pp_data->cap[178]->LinkUsagePage = 0xFF01
8674pp_data->cap[178]->LinkUsage = 0x0080
8675pp_data->cap[178]->IsMultipleItemsForArray = 0
8676pp_data->cap[178]->IsButtonCap = 0
8677pp_data->cap[178]->IsPadding = 0
8678pp_data->cap[178]->IsAbsolute = 1
8679pp_data->cap[178]->IsRange = 0
8680pp_data->cap[178]->IsAlias = 0
8681pp_data->cap[178]->IsStringRange = 0
8682pp_data->cap[178]->IsDesignatorRange = 0
8683pp_data->cap[178]->Reserved1 = 0x000000
8684pp_data->cap[178]->pp_cap->UnknownTokens[0].Token = 0x00
8685pp_data->cap[178]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8686pp_data->cap[178]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8687pp_data->cap[178]->pp_cap->UnknownTokens[1].Token = 0x00
8688pp_data->cap[178]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8689pp_data->cap[178]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8690pp_data->cap[178]->pp_cap->UnknownTokens[2].Token = 0x00
8691pp_data->cap[178]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8692pp_data->cap[178]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8693pp_data->cap[178]->pp_cap->UnknownTokens[3].Token = 0x00
8694pp_data->cap[178]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8695pp_data->cap[178]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8696pp_data->cap[178]->NotRange.Usage = 0x0081
8697pp_data->cap[178]->NotRange.Reserved1 = 0x0081
8698pp_data->cap[178]->NotRange.StringIndex = 0
8699pp_data->cap[178]->NotRange.Reserved2 = 0
8700pp_data->cap[178]->NotRange.DesignatorIndex = 0
8701pp_data->cap[178]->NotRange.Reserved3 = 0
8702pp_data->cap[178]->NotRange.DataIndex = 91
8703pp_data->cap[178]->NotRange.Reserved4 = 91
8704pp_data->cap[178]->NotButton.HasNull = 0
8705pp_data->cap[178]->NotButton.Reserved4 = 0x000000
8706pp_data->cap[178]->NotButton.LogicalMin = 0
8707pp_data->cap[178]->NotButton.LogicalMax = 127
8708pp_data->cap[178]->NotButton.PhysicalMin = 0
8709pp_data->cap[178]->NotButton.PhysicalMax = 0
8710pp_data->cap[178]->Units = 0
8711pp_data->cap[178]->UnitsExp = 0
8712
8713pp_data->cap[179]->UsagePage = 0xFF01
8714pp_data->cap[179]->ReportID = 0x80
8715pp_data->cap[179]->BitPosition = 0
8716pp_data->cap[179]->BitSize = 8
8717pp_data->cap[179]->ReportCount = 1
8718pp_data->cap[179]->BytePosition = 0x0002
8719pp_data->cap[179]->BitCount = 8
8720pp_data->cap[179]->BitField = 0x02
8721pp_data->cap[179]->NextBytePosition = 0x0003
8722pp_data->cap[179]->LinkCollection = 0x0003
8723pp_data->cap[179]->LinkUsagePage = 0xFF01
8724pp_data->cap[179]->LinkUsage = 0x0080
8725pp_data->cap[179]->IsMultipleItemsForArray = 0
8726pp_data->cap[179]->IsButtonCap = 0
8727pp_data->cap[179]->IsPadding = 0
8728pp_data->cap[179]->IsAbsolute = 1
8729pp_data->cap[179]->IsRange = 0
8730pp_data->cap[179]->IsAlias = 0
8731pp_data->cap[179]->IsStringRange = 0
8732pp_data->cap[179]->IsDesignatorRange = 0
8733pp_data->cap[179]->Reserved1 = 0x000000
8734pp_data->cap[179]->pp_cap->UnknownTokens[0].Token = 0x00
8735pp_data->cap[179]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8736pp_data->cap[179]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8737pp_data->cap[179]->pp_cap->UnknownTokens[1].Token = 0x00
8738pp_data->cap[179]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8739pp_data->cap[179]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8740pp_data->cap[179]->pp_cap->UnknownTokens[2].Token = 0x00
8741pp_data->cap[179]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8742pp_data->cap[179]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8743pp_data->cap[179]->pp_cap->UnknownTokens[3].Token = 0x00
8744pp_data->cap[179]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8745pp_data->cap[179]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8746pp_data->cap[179]->NotRange.Usage = 0x0081
8747pp_data->cap[179]->NotRange.Reserved1 = 0x0081
8748pp_data->cap[179]->NotRange.StringIndex = 0
8749pp_data->cap[179]->NotRange.Reserved2 = 0
8750pp_data->cap[179]->NotRange.DesignatorIndex = 0
8751pp_data->cap[179]->NotRange.Reserved3 = 0
8752pp_data->cap[179]->NotRange.DataIndex = 92
8753pp_data->cap[179]->NotRange.Reserved4 = 92
8754pp_data->cap[179]->NotButton.HasNull = 0
8755pp_data->cap[179]->NotButton.Reserved4 = 0x000000
8756pp_data->cap[179]->NotButton.LogicalMin = 0
8757pp_data->cap[179]->NotButton.LogicalMax = 127
8758pp_data->cap[179]->NotButton.PhysicalMin = 0
8759pp_data->cap[179]->NotButton.PhysicalMax = 0
8760pp_data->cap[179]->Units = 0
8761pp_data->cap[179]->UnitsExp = 0
8762
8763pp_data->cap[180]->UsagePage = 0xFF01
8764pp_data->cap[180]->ReportID = 0x80
8765pp_data->cap[180]->BitPosition = 0
8766pp_data->cap[180]->BitSize = 8
8767pp_data->cap[180]->ReportCount = 1
8768pp_data->cap[180]->BytePosition = 0x0001
8769pp_data->cap[180]->BitCount = 8
8770pp_data->cap[180]->BitField = 0x02
8771pp_data->cap[180]->NextBytePosition = 0x0002
8772pp_data->cap[180]->LinkCollection = 0x0003
8773pp_data->cap[180]->LinkUsagePage = 0xFF01
8774pp_data->cap[180]->LinkUsage = 0x0080
8775pp_data->cap[180]->IsMultipleItemsForArray = 0
8776pp_data->cap[180]->IsButtonCap = 0
8777pp_data->cap[180]->IsPadding = 0
8778pp_data->cap[180]->IsAbsolute = 1
8779pp_data->cap[180]->IsRange = 0
8780pp_data->cap[180]->IsAlias = 0
8781pp_data->cap[180]->IsStringRange = 0
8782pp_data->cap[180]->IsDesignatorRange = 0
8783pp_data->cap[180]->Reserved1 = 0x000000
8784pp_data->cap[180]->pp_cap->UnknownTokens[0].Token = 0x00
8785pp_data->cap[180]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8786pp_data->cap[180]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8787pp_data->cap[180]->pp_cap->UnknownTokens[1].Token = 0x00
8788pp_data->cap[180]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8789pp_data->cap[180]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8790pp_data->cap[180]->pp_cap->UnknownTokens[2].Token = 0x00
8791pp_data->cap[180]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8792pp_data->cap[180]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8793pp_data->cap[180]->pp_cap->UnknownTokens[3].Token = 0x00
8794pp_data->cap[180]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8795pp_data->cap[180]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8796pp_data->cap[180]->NotRange.Usage = 0x0081
8797pp_data->cap[180]->NotRange.Reserved1 = 0x0081
8798pp_data->cap[180]->NotRange.StringIndex = 0
8799pp_data->cap[180]->NotRange.Reserved2 = 0
8800pp_data->cap[180]->NotRange.DesignatorIndex = 0
8801pp_data->cap[180]->NotRange.Reserved3 = 0
8802pp_data->cap[180]->NotRange.DataIndex = 93
8803pp_data->cap[180]->NotRange.Reserved4 = 93
8804pp_data->cap[180]->NotButton.HasNull = 0
8805pp_data->cap[180]->NotButton.Reserved4 = 0x000000
8806pp_data->cap[180]->NotButton.LogicalMin = 0
8807pp_data->cap[180]->NotButton.LogicalMax = 127
8808pp_data->cap[180]->NotButton.PhysicalMin = 0
8809pp_data->cap[180]->NotButton.PhysicalMax = 0
8810pp_data->cap[180]->Units = 0
8811pp_data->cap[180]->UnitsExp = 0
8812
8813pp_data->cap[181]->UsagePage = 0xFF01
8814pp_data->cap[181]->ReportID = 0x81
8815pp_data->cap[181]->BitPosition = 0
8816pp_data->cap[181]->BitSize = 8
8817pp_data->cap[181]->ReportCount = 1
8818pp_data->cap[181]->BytePosition = 0x0028
8819pp_data->cap[181]->BitCount = 8
8820pp_data->cap[181]->BitField = 0x02
8821pp_data->cap[181]->NextBytePosition = 0x0029
8822pp_data->cap[181]->LinkCollection = 0x0004
8823pp_data->cap[181]->LinkUsagePage = 0xFF01
8824pp_data->cap[181]->LinkUsage = 0x0080
8825pp_data->cap[181]->IsMultipleItemsForArray = 0
8826pp_data->cap[181]->IsButtonCap = 0
8827pp_data->cap[181]->IsPadding = 0
8828pp_data->cap[181]->IsAbsolute = 1
8829pp_data->cap[181]->IsRange = 0
8830pp_data->cap[181]->IsAlias = 0
8831pp_data->cap[181]->IsStringRange = 0
8832pp_data->cap[181]->IsDesignatorRange = 0
8833pp_data->cap[181]->Reserved1 = 0x000000
8834pp_data->cap[181]->pp_cap->UnknownTokens[0].Token = 0x00
8835pp_data->cap[181]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8836pp_data->cap[181]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8837pp_data->cap[181]->pp_cap->UnknownTokens[1].Token = 0x00
8838pp_data->cap[181]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8839pp_data->cap[181]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8840pp_data->cap[181]->pp_cap->UnknownTokens[2].Token = 0x00
8841pp_data->cap[181]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8842pp_data->cap[181]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8843pp_data->cap[181]->pp_cap->UnknownTokens[3].Token = 0x00
8844pp_data->cap[181]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8845pp_data->cap[181]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8846pp_data->cap[181]->NotRange.Usage = 0x0081
8847pp_data->cap[181]->NotRange.Reserved1 = 0x0081
8848pp_data->cap[181]->NotRange.StringIndex = 0
8849pp_data->cap[181]->NotRange.Reserved2 = 0
8850pp_data->cap[181]->NotRange.DesignatorIndex = 0
8851pp_data->cap[181]->NotRange.Reserved3 = 0
8852pp_data->cap[181]->NotRange.DataIndex = 94
8853pp_data->cap[181]->NotRange.Reserved4 = 94
8854pp_data->cap[181]->NotButton.HasNull = 0
8855pp_data->cap[181]->NotButton.Reserved4 = 0x000000
8856pp_data->cap[181]->NotButton.LogicalMin = 0
8857pp_data->cap[181]->NotButton.LogicalMax = 127
8858pp_data->cap[181]->NotButton.PhysicalMin = 0
8859pp_data->cap[181]->NotButton.PhysicalMax = 0
8860pp_data->cap[181]->Units = 0
8861pp_data->cap[181]->UnitsExp = 0
8862
8863pp_data->cap[182]->UsagePage = 0xFF01
8864pp_data->cap[182]->ReportID = 0x81
8865pp_data->cap[182]->BitPosition = 0
8866pp_data->cap[182]->BitSize = 8
8867pp_data->cap[182]->ReportCount = 1
8868pp_data->cap[182]->BytePosition = 0x0027
8869pp_data->cap[182]->BitCount = 8
8870pp_data->cap[182]->BitField = 0x02
8871pp_data->cap[182]->NextBytePosition = 0x0028
8872pp_data->cap[182]->LinkCollection = 0x0004
8873pp_data->cap[182]->LinkUsagePage = 0xFF01
8874pp_data->cap[182]->LinkUsage = 0x0080
8875pp_data->cap[182]->IsMultipleItemsForArray = 0
8876pp_data->cap[182]->IsButtonCap = 0
8877pp_data->cap[182]->IsPadding = 0
8878pp_data->cap[182]->IsAbsolute = 1
8879pp_data->cap[182]->IsRange = 0
8880pp_data->cap[182]->IsAlias = 0
8881pp_data->cap[182]->IsStringRange = 0
8882pp_data->cap[182]->IsDesignatorRange = 0
8883pp_data->cap[182]->Reserved1 = 0x000000
8884pp_data->cap[182]->pp_cap->UnknownTokens[0].Token = 0x00
8885pp_data->cap[182]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8886pp_data->cap[182]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8887pp_data->cap[182]->pp_cap->UnknownTokens[1].Token = 0x00
8888pp_data->cap[182]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8889pp_data->cap[182]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8890pp_data->cap[182]->pp_cap->UnknownTokens[2].Token = 0x00
8891pp_data->cap[182]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8892pp_data->cap[182]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8893pp_data->cap[182]->pp_cap->UnknownTokens[3].Token = 0x00
8894pp_data->cap[182]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8895pp_data->cap[182]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8896pp_data->cap[182]->NotRange.Usage = 0x0081
8897pp_data->cap[182]->NotRange.Reserved1 = 0x0081
8898pp_data->cap[182]->NotRange.StringIndex = 0
8899pp_data->cap[182]->NotRange.Reserved2 = 0
8900pp_data->cap[182]->NotRange.DesignatorIndex = 0
8901pp_data->cap[182]->NotRange.Reserved3 = 0
8902pp_data->cap[182]->NotRange.DataIndex = 95
8903pp_data->cap[182]->NotRange.Reserved4 = 95
8904pp_data->cap[182]->NotButton.HasNull = 0
8905pp_data->cap[182]->NotButton.Reserved4 = 0x000000
8906pp_data->cap[182]->NotButton.LogicalMin = 0
8907pp_data->cap[182]->NotButton.LogicalMax = 127
8908pp_data->cap[182]->NotButton.PhysicalMin = 0
8909pp_data->cap[182]->NotButton.PhysicalMax = 0
8910pp_data->cap[182]->Units = 0
8911pp_data->cap[182]->UnitsExp = 0
8912
8913pp_data->cap[183]->UsagePage = 0xFF01
8914pp_data->cap[183]->ReportID = 0x81
8915pp_data->cap[183]->BitPosition = 0
8916pp_data->cap[183]->BitSize = 8
8917pp_data->cap[183]->ReportCount = 1
8918pp_data->cap[183]->BytePosition = 0x0026
8919pp_data->cap[183]->BitCount = 8
8920pp_data->cap[183]->BitField = 0x02
8921pp_data->cap[183]->NextBytePosition = 0x0027
8922pp_data->cap[183]->LinkCollection = 0x0004
8923pp_data->cap[183]->LinkUsagePage = 0xFF01
8924pp_data->cap[183]->LinkUsage = 0x0080
8925pp_data->cap[183]->IsMultipleItemsForArray = 0
8926pp_data->cap[183]->IsButtonCap = 0
8927pp_data->cap[183]->IsPadding = 0
8928pp_data->cap[183]->IsAbsolute = 1
8929pp_data->cap[183]->IsRange = 0
8930pp_data->cap[183]->IsAlias = 0
8931pp_data->cap[183]->IsStringRange = 0
8932pp_data->cap[183]->IsDesignatorRange = 0
8933pp_data->cap[183]->Reserved1 = 0x000000
8934pp_data->cap[183]->pp_cap->UnknownTokens[0].Token = 0x00
8935pp_data->cap[183]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8936pp_data->cap[183]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8937pp_data->cap[183]->pp_cap->UnknownTokens[1].Token = 0x00
8938pp_data->cap[183]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8939pp_data->cap[183]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8940pp_data->cap[183]->pp_cap->UnknownTokens[2].Token = 0x00
8941pp_data->cap[183]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8942pp_data->cap[183]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8943pp_data->cap[183]->pp_cap->UnknownTokens[3].Token = 0x00
8944pp_data->cap[183]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8945pp_data->cap[183]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8946pp_data->cap[183]->NotRange.Usage = 0x0081
8947pp_data->cap[183]->NotRange.Reserved1 = 0x0081
8948pp_data->cap[183]->NotRange.StringIndex = 0
8949pp_data->cap[183]->NotRange.Reserved2 = 0
8950pp_data->cap[183]->NotRange.DesignatorIndex = 0
8951pp_data->cap[183]->NotRange.Reserved3 = 0
8952pp_data->cap[183]->NotRange.DataIndex = 96
8953pp_data->cap[183]->NotRange.Reserved4 = 96
8954pp_data->cap[183]->NotButton.HasNull = 0
8955pp_data->cap[183]->NotButton.Reserved4 = 0x000000
8956pp_data->cap[183]->NotButton.LogicalMin = 0
8957pp_data->cap[183]->NotButton.LogicalMax = 127
8958pp_data->cap[183]->NotButton.PhysicalMin = 0
8959pp_data->cap[183]->NotButton.PhysicalMax = 0
8960pp_data->cap[183]->Units = 0
8961pp_data->cap[183]->UnitsExp = 0
8962
8963pp_data->cap[184]->UsagePage = 0xFF01
8964pp_data->cap[184]->ReportID = 0x81
8965pp_data->cap[184]->BitPosition = 0
8966pp_data->cap[184]->BitSize = 8
8967pp_data->cap[184]->ReportCount = 1
8968pp_data->cap[184]->BytePosition = 0x0025
8969pp_data->cap[184]->BitCount = 8
8970pp_data->cap[184]->BitField = 0x02
8971pp_data->cap[184]->NextBytePosition = 0x0026
8972pp_data->cap[184]->LinkCollection = 0x0004
8973pp_data->cap[184]->LinkUsagePage = 0xFF01
8974pp_data->cap[184]->LinkUsage = 0x0080
8975pp_data->cap[184]->IsMultipleItemsForArray = 0
8976pp_data->cap[184]->IsButtonCap = 0
8977pp_data->cap[184]->IsPadding = 0
8978pp_data->cap[184]->IsAbsolute = 1
8979pp_data->cap[184]->IsRange = 0
8980pp_data->cap[184]->IsAlias = 0
8981pp_data->cap[184]->IsStringRange = 0
8982pp_data->cap[184]->IsDesignatorRange = 0
8983pp_data->cap[184]->Reserved1 = 0x000000
8984pp_data->cap[184]->pp_cap->UnknownTokens[0].Token = 0x00
8985pp_data->cap[184]->pp_cap->UnknownTokens[0].Reserved = 0x000000
8986pp_data->cap[184]->pp_cap->UnknownTokens[0].BitField = 0x00000000
8987pp_data->cap[184]->pp_cap->UnknownTokens[1].Token = 0x00
8988pp_data->cap[184]->pp_cap->UnknownTokens[1].Reserved = 0x000000
8989pp_data->cap[184]->pp_cap->UnknownTokens[1].BitField = 0x00000000
8990pp_data->cap[184]->pp_cap->UnknownTokens[2].Token = 0x00
8991pp_data->cap[184]->pp_cap->UnknownTokens[2].Reserved = 0x000000
8992pp_data->cap[184]->pp_cap->UnknownTokens[2].BitField = 0x00000000
8993pp_data->cap[184]->pp_cap->UnknownTokens[3].Token = 0x00
8994pp_data->cap[184]->pp_cap->UnknownTokens[3].Reserved = 0x000000
8995pp_data->cap[184]->pp_cap->UnknownTokens[3].BitField = 0x00000000
8996pp_data->cap[184]->NotRange.Usage = 0x0081
8997pp_data->cap[184]->NotRange.Reserved1 = 0x0081
8998pp_data->cap[184]->NotRange.StringIndex = 0
8999pp_data->cap[184]->NotRange.Reserved2 = 0
9000pp_data->cap[184]->NotRange.DesignatorIndex = 0
9001pp_data->cap[184]->NotRange.Reserved3 = 0
9002pp_data->cap[184]->NotRange.DataIndex = 97
9003pp_data->cap[184]->NotRange.Reserved4 = 97
9004pp_data->cap[184]->NotButton.HasNull = 0
9005pp_data->cap[184]->NotButton.Reserved4 = 0x000000
9006pp_data->cap[184]->NotButton.LogicalMin = 0
9007pp_data->cap[184]->NotButton.LogicalMax = 127
9008pp_data->cap[184]->NotButton.PhysicalMin = 0
9009pp_data->cap[184]->NotButton.PhysicalMax = 0
9010pp_data->cap[184]->Units = 0
9011pp_data->cap[184]->UnitsExp = 0
9012
9013pp_data->cap[185]->UsagePage = 0xFF01
9014pp_data->cap[185]->ReportID = 0x81
9015pp_data->cap[185]->BitPosition = 0
9016pp_data->cap[185]->BitSize = 8
9017pp_data->cap[185]->ReportCount = 1
9018pp_data->cap[185]->BytePosition = 0x0024
9019pp_data->cap[185]->BitCount = 8
9020pp_data->cap[185]->BitField = 0x02
9021pp_data->cap[185]->NextBytePosition = 0x0025
9022pp_data->cap[185]->LinkCollection = 0x0004
9023pp_data->cap[185]->LinkUsagePage = 0xFF01
9024pp_data->cap[185]->LinkUsage = 0x0080
9025pp_data->cap[185]->IsMultipleItemsForArray = 0
9026pp_data->cap[185]->IsButtonCap = 0
9027pp_data->cap[185]->IsPadding = 0
9028pp_data->cap[185]->IsAbsolute = 1
9029pp_data->cap[185]->IsRange = 0
9030pp_data->cap[185]->IsAlias = 0
9031pp_data->cap[185]->IsStringRange = 0
9032pp_data->cap[185]->IsDesignatorRange = 0
9033pp_data->cap[185]->Reserved1 = 0x000000
9034pp_data->cap[185]->pp_cap->UnknownTokens[0].Token = 0x00
9035pp_data->cap[185]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9036pp_data->cap[185]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9037pp_data->cap[185]->pp_cap->UnknownTokens[1].Token = 0x00
9038pp_data->cap[185]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9039pp_data->cap[185]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9040pp_data->cap[185]->pp_cap->UnknownTokens[2].Token = 0x00
9041pp_data->cap[185]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9042pp_data->cap[185]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9043pp_data->cap[185]->pp_cap->UnknownTokens[3].Token = 0x00
9044pp_data->cap[185]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9045pp_data->cap[185]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9046pp_data->cap[185]->NotRange.Usage = 0x0081
9047pp_data->cap[185]->NotRange.Reserved1 = 0x0081
9048pp_data->cap[185]->NotRange.StringIndex = 0
9049pp_data->cap[185]->NotRange.Reserved2 = 0
9050pp_data->cap[185]->NotRange.DesignatorIndex = 0
9051pp_data->cap[185]->NotRange.Reserved3 = 0
9052pp_data->cap[185]->NotRange.DataIndex = 98
9053pp_data->cap[185]->NotRange.Reserved4 = 98
9054pp_data->cap[185]->NotButton.HasNull = 0
9055pp_data->cap[185]->NotButton.Reserved4 = 0x000000
9056pp_data->cap[185]->NotButton.LogicalMin = 0
9057pp_data->cap[185]->NotButton.LogicalMax = 127
9058pp_data->cap[185]->NotButton.PhysicalMin = 0
9059pp_data->cap[185]->NotButton.PhysicalMax = 0
9060pp_data->cap[185]->Units = 0
9061pp_data->cap[185]->UnitsExp = 0
9062
9063pp_data->cap[186]->UsagePage = 0xFF01
9064pp_data->cap[186]->ReportID = 0x81
9065pp_data->cap[186]->BitPosition = 0
9066pp_data->cap[186]->BitSize = 8
9067pp_data->cap[186]->ReportCount = 1
9068pp_data->cap[186]->BytePosition = 0x0023
9069pp_data->cap[186]->BitCount = 8
9070pp_data->cap[186]->BitField = 0x02
9071pp_data->cap[186]->NextBytePosition = 0x0024
9072pp_data->cap[186]->LinkCollection = 0x0004
9073pp_data->cap[186]->LinkUsagePage = 0xFF01
9074pp_data->cap[186]->LinkUsage = 0x0080
9075pp_data->cap[186]->IsMultipleItemsForArray = 0
9076pp_data->cap[186]->IsButtonCap = 0
9077pp_data->cap[186]->IsPadding = 0
9078pp_data->cap[186]->IsAbsolute = 1
9079pp_data->cap[186]->IsRange = 0
9080pp_data->cap[186]->IsAlias = 0
9081pp_data->cap[186]->IsStringRange = 0
9082pp_data->cap[186]->IsDesignatorRange = 0
9083pp_data->cap[186]->Reserved1 = 0x000000
9084pp_data->cap[186]->pp_cap->UnknownTokens[0].Token = 0x00
9085pp_data->cap[186]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9086pp_data->cap[186]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9087pp_data->cap[186]->pp_cap->UnknownTokens[1].Token = 0x00
9088pp_data->cap[186]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9089pp_data->cap[186]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9090pp_data->cap[186]->pp_cap->UnknownTokens[2].Token = 0x00
9091pp_data->cap[186]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9092pp_data->cap[186]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9093pp_data->cap[186]->pp_cap->UnknownTokens[3].Token = 0x00
9094pp_data->cap[186]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9095pp_data->cap[186]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9096pp_data->cap[186]->NotRange.Usage = 0x0081
9097pp_data->cap[186]->NotRange.Reserved1 = 0x0081
9098pp_data->cap[186]->NotRange.StringIndex = 0
9099pp_data->cap[186]->NotRange.Reserved2 = 0
9100pp_data->cap[186]->NotRange.DesignatorIndex = 0
9101pp_data->cap[186]->NotRange.Reserved3 = 0
9102pp_data->cap[186]->NotRange.DataIndex = 99
9103pp_data->cap[186]->NotRange.Reserved4 = 99
9104pp_data->cap[186]->NotButton.HasNull = 0
9105pp_data->cap[186]->NotButton.Reserved4 = 0x000000
9106pp_data->cap[186]->NotButton.LogicalMin = 0
9107pp_data->cap[186]->NotButton.LogicalMax = 127
9108pp_data->cap[186]->NotButton.PhysicalMin = 0
9109pp_data->cap[186]->NotButton.PhysicalMax = 0
9110pp_data->cap[186]->Units = 0
9111pp_data->cap[186]->UnitsExp = 0
9112
9113pp_data->cap[187]->UsagePage = 0xFF01
9114pp_data->cap[187]->ReportID = 0x81
9115pp_data->cap[187]->BitPosition = 0
9116pp_data->cap[187]->BitSize = 8
9117pp_data->cap[187]->ReportCount = 1
9118pp_data->cap[187]->BytePosition = 0x0022
9119pp_data->cap[187]->BitCount = 8
9120pp_data->cap[187]->BitField = 0x02
9121pp_data->cap[187]->NextBytePosition = 0x0023
9122pp_data->cap[187]->LinkCollection = 0x0004
9123pp_data->cap[187]->LinkUsagePage = 0xFF01
9124pp_data->cap[187]->LinkUsage = 0x0080
9125pp_data->cap[187]->IsMultipleItemsForArray = 0
9126pp_data->cap[187]->IsButtonCap = 0
9127pp_data->cap[187]->IsPadding = 0
9128pp_data->cap[187]->IsAbsolute = 1
9129pp_data->cap[187]->IsRange = 0
9130pp_data->cap[187]->IsAlias = 0
9131pp_data->cap[187]->IsStringRange = 0
9132pp_data->cap[187]->IsDesignatorRange = 0
9133pp_data->cap[187]->Reserved1 = 0x000000
9134pp_data->cap[187]->pp_cap->UnknownTokens[0].Token = 0x00
9135pp_data->cap[187]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9136pp_data->cap[187]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9137pp_data->cap[187]->pp_cap->UnknownTokens[1].Token = 0x00
9138pp_data->cap[187]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9139pp_data->cap[187]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9140pp_data->cap[187]->pp_cap->UnknownTokens[2].Token = 0x00
9141pp_data->cap[187]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9142pp_data->cap[187]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9143pp_data->cap[187]->pp_cap->UnknownTokens[3].Token = 0x00
9144pp_data->cap[187]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9145pp_data->cap[187]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9146pp_data->cap[187]->NotRange.Usage = 0x0081
9147pp_data->cap[187]->NotRange.Reserved1 = 0x0081
9148pp_data->cap[187]->NotRange.StringIndex = 0
9149pp_data->cap[187]->NotRange.Reserved2 = 0
9150pp_data->cap[187]->NotRange.DesignatorIndex = 0
9151pp_data->cap[187]->NotRange.Reserved3 = 0
9152pp_data->cap[187]->NotRange.DataIndex = 100
9153pp_data->cap[187]->NotRange.Reserved4 = 100
9154pp_data->cap[187]->NotButton.HasNull = 0
9155pp_data->cap[187]->NotButton.Reserved4 = 0x000000
9156pp_data->cap[187]->NotButton.LogicalMin = 0
9157pp_data->cap[187]->NotButton.LogicalMax = 127
9158pp_data->cap[187]->NotButton.PhysicalMin = 0
9159pp_data->cap[187]->NotButton.PhysicalMax = 0
9160pp_data->cap[187]->Units = 0
9161pp_data->cap[187]->UnitsExp = 0
9162
9163pp_data->cap[188]->UsagePage = 0xFF01
9164pp_data->cap[188]->ReportID = 0x81
9165pp_data->cap[188]->BitPosition = 0
9166pp_data->cap[188]->BitSize = 8
9167pp_data->cap[188]->ReportCount = 1
9168pp_data->cap[188]->BytePosition = 0x0021
9169pp_data->cap[188]->BitCount = 8
9170pp_data->cap[188]->BitField = 0x02
9171pp_data->cap[188]->NextBytePosition = 0x0022
9172pp_data->cap[188]->LinkCollection = 0x0004
9173pp_data->cap[188]->LinkUsagePage = 0xFF01
9174pp_data->cap[188]->LinkUsage = 0x0080
9175pp_data->cap[188]->IsMultipleItemsForArray = 0
9176pp_data->cap[188]->IsButtonCap = 0
9177pp_data->cap[188]->IsPadding = 0
9178pp_data->cap[188]->IsAbsolute = 1
9179pp_data->cap[188]->IsRange = 0
9180pp_data->cap[188]->IsAlias = 0
9181pp_data->cap[188]->IsStringRange = 0
9182pp_data->cap[188]->IsDesignatorRange = 0
9183pp_data->cap[188]->Reserved1 = 0x000000
9184pp_data->cap[188]->pp_cap->UnknownTokens[0].Token = 0x00
9185pp_data->cap[188]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9186pp_data->cap[188]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9187pp_data->cap[188]->pp_cap->UnknownTokens[1].Token = 0x00
9188pp_data->cap[188]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9189pp_data->cap[188]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9190pp_data->cap[188]->pp_cap->UnknownTokens[2].Token = 0x00
9191pp_data->cap[188]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9192pp_data->cap[188]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9193pp_data->cap[188]->pp_cap->UnknownTokens[3].Token = 0x00
9194pp_data->cap[188]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9195pp_data->cap[188]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9196pp_data->cap[188]->NotRange.Usage = 0x0081
9197pp_data->cap[188]->NotRange.Reserved1 = 0x0081
9198pp_data->cap[188]->NotRange.StringIndex = 0
9199pp_data->cap[188]->NotRange.Reserved2 = 0
9200pp_data->cap[188]->NotRange.DesignatorIndex = 0
9201pp_data->cap[188]->NotRange.Reserved3 = 0
9202pp_data->cap[188]->NotRange.DataIndex = 101
9203pp_data->cap[188]->NotRange.Reserved4 = 101
9204pp_data->cap[188]->NotButton.HasNull = 0
9205pp_data->cap[188]->NotButton.Reserved4 = 0x000000
9206pp_data->cap[188]->NotButton.LogicalMin = 0
9207pp_data->cap[188]->NotButton.LogicalMax = 127
9208pp_data->cap[188]->NotButton.PhysicalMin = 0
9209pp_data->cap[188]->NotButton.PhysicalMax = 0
9210pp_data->cap[188]->Units = 0
9211pp_data->cap[188]->UnitsExp = 0
9212
9213pp_data->cap[189]->UsagePage = 0xFF01
9214pp_data->cap[189]->ReportID = 0x81
9215pp_data->cap[189]->BitPosition = 0
9216pp_data->cap[189]->BitSize = 8
9217pp_data->cap[189]->ReportCount = 1
9218pp_data->cap[189]->BytePosition = 0x0020
9219pp_data->cap[189]->BitCount = 8
9220pp_data->cap[189]->BitField = 0x02
9221pp_data->cap[189]->NextBytePosition = 0x0021
9222pp_data->cap[189]->LinkCollection = 0x0004
9223pp_data->cap[189]->LinkUsagePage = 0xFF01
9224pp_data->cap[189]->LinkUsage = 0x0080
9225pp_data->cap[189]->IsMultipleItemsForArray = 0
9226pp_data->cap[189]->IsButtonCap = 0
9227pp_data->cap[189]->IsPadding = 0
9228pp_data->cap[189]->IsAbsolute = 1
9229pp_data->cap[189]->IsRange = 0
9230pp_data->cap[189]->IsAlias = 0
9231pp_data->cap[189]->IsStringRange = 0
9232pp_data->cap[189]->IsDesignatorRange = 0
9233pp_data->cap[189]->Reserved1 = 0x000000
9234pp_data->cap[189]->pp_cap->UnknownTokens[0].Token = 0x00
9235pp_data->cap[189]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9236pp_data->cap[189]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9237pp_data->cap[189]->pp_cap->UnknownTokens[1].Token = 0x00
9238pp_data->cap[189]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9239pp_data->cap[189]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9240pp_data->cap[189]->pp_cap->UnknownTokens[2].Token = 0x00
9241pp_data->cap[189]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9242pp_data->cap[189]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9243pp_data->cap[189]->pp_cap->UnknownTokens[3].Token = 0x00
9244pp_data->cap[189]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9245pp_data->cap[189]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9246pp_data->cap[189]->NotRange.Usage = 0x0081
9247pp_data->cap[189]->NotRange.Reserved1 = 0x0081
9248pp_data->cap[189]->NotRange.StringIndex = 0
9249pp_data->cap[189]->NotRange.Reserved2 = 0
9250pp_data->cap[189]->NotRange.DesignatorIndex = 0
9251pp_data->cap[189]->NotRange.Reserved3 = 0
9252pp_data->cap[189]->NotRange.DataIndex = 102
9253pp_data->cap[189]->NotRange.Reserved4 = 102
9254pp_data->cap[189]->NotButton.HasNull = 0
9255pp_data->cap[189]->NotButton.Reserved4 = 0x000000
9256pp_data->cap[189]->NotButton.LogicalMin = 0
9257pp_data->cap[189]->NotButton.LogicalMax = 127
9258pp_data->cap[189]->NotButton.PhysicalMin = 0
9259pp_data->cap[189]->NotButton.PhysicalMax = 0
9260pp_data->cap[189]->Units = 0
9261pp_data->cap[189]->UnitsExp = 0
9262
9263pp_data->cap[190]->UsagePage = 0xFF01
9264pp_data->cap[190]->ReportID = 0x81
9265pp_data->cap[190]->BitPosition = 0
9266pp_data->cap[190]->BitSize = 8
9267pp_data->cap[190]->ReportCount = 1
9268pp_data->cap[190]->BytePosition = 0x001F
9269pp_data->cap[190]->BitCount = 8
9270pp_data->cap[190]->BitField = 0x02
9271pp_data->cap[190]->NextBytePosition = 0x0020
9272pp_data->cap[190]->LinkCollection = 0x0004
9273pp_data->cap[190]->LinkUsagePage = 0xFF01
9274pp_data->cap[190]->LinkUsage = 0x0080
9275pp_data->cap[190]->IsMultipleItemsForArray = 0
9276pp_data->cap[190]->IsButtonCap = 0
9277pp_data->cap[190]->IsPadding = 0
9278pp_data->cap[190]->IsAbsolute = 1
9279pp_data->cap[190]->IsRange = 0
9280pp_data->cap[190]->IsAlias = 0
9281pp_data->cap[190]->IsStringRange = 0
9282pp_data->cap[190]->IsDesignatorRange = 0
9283pp_data->cap[190]->Reserved1 = 0x000000
9284pp_data->cap[190]->pp_cap->UnknownTokens[0].Token = 0x00
9285pp_data->cap[190]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9286pp_data->cap[190]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9287pp_data->cap[190]->pp_cap->UnknownTokens[1].Token = 0x00
9288pp_data->cap[190]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9289pp_data->cap[190]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9290pp_data->cap[190]->pp_cap->UnknownTokens[2].Token = 0x00
9291pp_data->cap[190]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9292pp_data->cap[190]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9293pp_data->cap[190]->pp_cap->UnknownTokens[3].Token = 0x00
9294pp_data->cap[190]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9295pp_data->cap[190]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9296pp_data->cap[190]->NotRange.Usage = 0x0081
9297pp_data->cap[190]->NotRange.Reserved1 = 0x0081
9298pp_data->cap[190]->NotRange.StringIndex = 0
9299pp_data->cap[190]->NotRange.Reserved2 = 0
9300pp_data->cap[190]->NotRange.DesignatorIndex = 0
9301pp_data->cap[190]->NotRange.Reserved3 = 0
9302pp_data->cap[190]->NotRange.DataIndex = 103
9303pp_data->cap[190]->NotRange.Reserved4 = 103
9304pp_data->cap[190]->NotButton.HasNull = 0
9305pp_data->cap[190]->NotButton.Reserved4 = 0x000000
9306pp_data->cap[190]->NotButton.LogicalMin = 0
9307pp_data->cap[190]->NotButton.LogicalMax = 127
9308pp_data->cap[190]->NotButton.PhysicalMin = 0
9309pp_data->cap[190]->NotButton.PhysicalMax = 0
9310pp_data->cap[190]->Units = 0
9311pp_data->cap[190]->UnitsExp = 0
9312
9313pp_data->cap[191]->UsagePage = 0xFF01
9314pp_data->cap[191]->ReportID = 0x81
9315pp_data->cap[191]->BitPosition = 0
9316pp_data->cap[191]->BitSize = 8
9317pp_data->cap[191]->ReportCount = 1
9318pp_data->cap[191]->BytePosition = 0x001E
9319pp_data->cap[191]->BitCount = 8
9320pp_data->cap[191]->BitField = 0x02
9321pp_data->cap[191]->NextBytePosition = 0x001F
9322pp_data->cap[191]->LinkCollection = 0x0004
9323pp_data->cap[191]->LinkUsagePage = 0xFF01
9324pp_data->cap[191]->LinkUsage = 0x0080
9325pp_data->cap[191]->IsMultipleItemsForArray = 0
9326pp_data->cap[191]->IsButtonCap = 0
9327pp_data->cap[191]->IsPadding = 0
9328pp_data->cap[191]->IsAbsolute = 1
9329pp_data->cap[191]->IsRange = 0
9330pp_data->cap[191]->IsAlias = 0
9331pp_data->cap[191]->IsStringRange = 0
9332pp_data->cap[191]->IsDesignatorRange = 0
9333pp_data->cap[191]->Reserved1 = 0x000000
9334pp_data->cap[191]->pp_cap->UnknownTokens[0].Token = 0x00
9335pp_data->cap[191]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9336pp_data->cap[191]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9337pp_data->cap[191]->pp_cap->UnknownTokens[1].Token = 0x00
9338pp_data->cap[191]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9339pp_data->cap[191]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9340pp_data->cap[191]->pp_cap->UnknownTokens[2].Token = 0x00
9341pp_data->cap[191]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9342pp_data->cap[191]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9343pp_data->cap[191]->pp_cap->UnknownTokens[3].Token = 0x00
9344pp_data->cap[191]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9345pp_data->cap[191]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9346pp_data->cap[191]->NotRange.Usage = 0x0081
9347pp_data->cap[191]->NotRange.Reserved1 = 0x0081
9348pp_data->cap[191]->NotRange.StringIndex = 0
9349pp_data->cap[191]->NotRange.Reserved2 = 0
9350pp_data->cap[191]->NotRange.DesignatorIndex = 0
9351pp_data->cap[191]->NotRange.Reserved3 = 0
9352pp_data->cap[191]->NotRange.DataIndex = 104
9353pp_data->cap[191]->NotRange.Reserved4 = 104
9354pp_data->cap[191]->NotButton.HasNull = 0
9355pp_data->cap[191]->NotButton.Reserved4 = 0x000000
9356pp_data->cap[191]->NotButton.LogicalMin = 0
9357pp_data->cap[191]->NotButton.LogicalMax = 127
9358pp_data->cap[191]->NotButton.PhysicalMin = 0
9359pp_data->cap[191]->NotButton.PhysicalMax = 0
9360pp_data->cap[191]->Units = 0
9361pp_data->cap[191]->UnitsExp = 0
9362
9363pp_data->cap[192]->UsagePage = 0xFF01
9364pp_data->cap[192]->ReportID = 0x81
9365pp_data->cap[192]->BitPosition = 0
9366pp_data->cap[192]->BitSize = 8
9367pp_data->cap[192]->ReportCount = 1
9368pp_data->cap[192]->BytePosition = 0x001D
9369pp_data->cap[192]->BitCount = 8
9370pp_data->cap[192]->BitField = 0x02
9371pp_data->cap[192]->NextBytePosition = 0x001E
9372pp_data->cap[192]->LinkCollection = 0x0004
9373pp_data->cap[192]->LinkUsagePage = 0xFF01
9374pp_data->cap[192]->LinkUsage = 0x0080
9375pp_data->cap[192]->IsMultipleItemsForArray = 0
9376pp_data->cap[192]->IsButtonCap = 0
9377pp_data->cap[192]->IsPadding = 0
9378pp_data->cap[192]->IsAbsolute = 1
9379pp_data->cap[192]->IsRange = 0
9380pp_data->cap[192]->IsAlias = 0
9381pp_data->cap[192]->IsStringRange = 0
9382pp_data->cap[192]->IsDesignatorRange = 0
9383pp_data->cap[192]->Reserved1 = 0x000000
9384pp_data->cap[192]->pp_cap->UnknownTokens[0].Token = 0x00
9385pp_data->cap[192]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9386pp_data->cap[192]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9387pp_data->cap[192]->pp_cap->UnknownTokens[1].Token = 0x00
9388pp_data->cap[192]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9389pp_data->cap[192]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9390pp_data->cap[192]->pp_cap->UnknownTokens[2].Token = 0x00
9391pp_data->cap[192]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9392pp_data->cap[192]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9393pp_data->cap[192]->pp_cap->UnknownTokens[3].Token = 0x00
9394pp_data->cap[192]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9395pp_data->cap[192]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9396pp_data->cap[192]->NotRange.Usage = 0x0081
9397pp_data->cap[192]->NotRange.Reserved1 = 0x0081
9398pp_data->cap[192]->NotRange.StringIndex = 0
9399pp_data->cap[192]->NotRange.Reserved2 = 0
9400pp_data->cap[192]->NotRange.DesignatorIndex = 0
9401pp_data->cap[192]->NotRange.Reserved3 = 0
9402pp_data->cap[192]->NotRange.DataIndex = 105
9403pp_data->cap[192]->NotRange.Reserved4 = 105
9404pp_data->cap[192]->NotButton.HasNull = 0
9405pp_data->cap[192]->NotButton.Reserved4 = 0x000000
9406pp_data->cap[192]->NotButton.LogicalMin = 0
9407pp_data->cap[192]->NotButton.LogicalMax = 127
9408pp_data->cap[192]->NotButton.PhysicalMin = 0
9409pp_data->cap[192]->NotButton.PhysicalMax = 0
9410pp_data->cap[192]->Units = 0
9411pp_data->cap[192]->UnitsExp = 0
9412
9413pp_data->cap[193]->UsagePage = 0xFF01
9414pp_data->cap[193]->ReportID = 0x81
9415pp_data->cap[193]->BitPosition = 0
9416pp_data->cap[193]->BitSize = 8
9417pp_data->cap[193]->ReportCount = 1
9418pp_data->cap[193]->BytePosition = 0x001C
9419pp_data->cap[193]->BitCount = 8
9420pp_data->cap[193]->BitField = 0x02
9421pp_data->cap[193]->NextBytePosition = 0x001D
9422pp_data->cap[193]->LinkCollection = 0x0004
9423pp_data->cap[193]->LinkUsagePage = 0xFF01
9424pp_data->cap[193]->LinkUsage = 0x0080
9425pp_data->cap[193]->IsMultipleItemsForArray = 0
9426pp_data->cap[193]->IsButtonCap = 0
9427pp_data->cap[193]->IsPadding = 0
9428pp_data->cap[193]->IsAbsolute = 1
9429pp_data->cap[193]->IsRange = 0
9430pp_data->cap[193]->IsAlias = 0
9431pp_data->cap[193]->IsStringRange = 0
9432pp_data->cap[193]->IsDesignatorRange = 0
9433pp_data->cap[193]->Reserved1 = 0x000000
9434pp_data->cap[193]->pp_cap->UnknownTokens[0].Token = 0x00
9435pp_data->cap[193]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9436pp_data->cap[193]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9437pp_data->cap[193]->pp_cap->UnknownTokens[1].Token = 0x00
9438pp_data->cap[193]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9439pp_data->cap[193]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9440pp_data->cap[193]->pp_cap->UnknownTokens[2].Token = 0x00
9441pp_data->cap[193]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9442pp_data->cap[193]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9443pp_data->cap[193]->pp_cap->UnknownTokens[3].Token = 0x00
9444pp_data->cap[193]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9445pp_data->cap[193]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9446pp_data->cap[193]->NotRange.Usage = 0x0081
9447pp_data->cap[193]->NotRange.Reserved1 = 0x0081
9448pp_data->cap[193]->NotRange.StringIndex = 0
9449pp_data->cap[193]->NotRange.Reserved2 = 0
9450pp_data->cap[193]->NotRange.DesignatorIndex = 0
9451pp_data->cap[193]->NotRange.Reserved3 = 0
9452pp_data->cap[193]->NotRange.DataIndex = 106
9453pp_data->cap[193]->NotRange.Reserved4 = 106
9454pp_data->cap[193]->NotButton.HasNull = 0
9455pp_data->cap[193]->NotButton.Reserved4 = 0x000000
9456pp_data->cap[193]->NotButton.LogicalMin = 0
9457pp_data->cap[193]->NotButton.LogicalMax = 127
9458pp_data->cap[193]->NotButton.PhysicalMin = 0
9459pp_data->cap[193]->NotButton.PhysicalMax = 0
9460pp_data->cap[193]->Units = 0
9461pp_data->cap[193]->UnitsExp = 0
9462
9463pp_data->cap[194]->UsagePage = 0xFF01
9464pp_data->cap[194]->ReportID = 0x81
9465pp_data->cap[194]->BitPosition = 0
9466pp_data->cap[194]->BitSize = 8
9467pp_data->cap[194]->ReportCount = 1
9468pp_data->cap[194]->BytePosition = 0x001B
9469pp_data->cap[194]->BitCount = 8
9470pp_data->cap[194]->BitField = 0x02
9471pp_data->cap[194]->NextBytePosition = 0x001C
9472pp_data->cap[194]->LinkCollection = 0x0004
9473pp_data->cap[194]->LinkUsagePage = 0xFF01
9474pp_data->cap[194]->LinkUsage = 0x0080
9475pp_data->cap[194]->IsMultipleItemsForArray = 0
9476pp_data->cap[194]->IsButtonCap = 0
9477pp_data->cap[194]->IsPadding = 0
9478pp_data->cap[194]->IsAbsolute = 1
9479pp_data->cap[194]->IsRange = 0
9480pp_data->cap[194]->IsAlias = 0
9481pp_data->cap[194]->IsStringRange = 0
9482pp_data->cap[194]->IsDesignatorRange = 0
9483pp_data->cap[194]->Reserved1 = 0x000000
9484pp_data->cap[194]->pp_cap->UnknownTokens[0].Token = 0x00
9485pp_data->cap[194]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9486pp_data->cap[194]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9487pp_data->cap[194]->pp_cap->UnknownTokens[1].Token = 0x00
9488pp_data->cap[194]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9489pp_data->cap[194]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9490pp_data->cap[194]->pp_cap->UnknownTokens[2].Token = 0x00
9491pp_data->cap[194]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9492pp_data->cap[194]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9493pp_data->cap[194]->pp_cap->UnknownTokens[3].Token = 0x00
9494pp_data->cap[194]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9495pp_data->cap[194]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9496pp_data->cap[194]->NotRange.Usage = 0x0081
9497pp_data->cap[194]->NotRange.Reserved1 = 0x0081
9498pp_data->cap[194]->NotRange.StringIndex = 0
9499pp_data->cap[194]->NotRange.Reserved2 = 0
9500pp_data->cap[194]->NotRange.DesignatorIndex = 0
9501pp_data->cap[194]->NotRange.Reserved3 = 0
9502pp_data->cap[194]->NotRange.DataIndex = 107
9503pp_data->cap[194]->NotRange.Reserved4 = 107
9504pp_data->cap[194]->NotButton.HasNull = 0
9505pp_data->cap[194]->NotButton.Reserved4 = 0x000000
9506pp_data->cap[194]->NotButton.LogicalMin = 0
9507pp_data->cap[194]->NotButton.LogicalMax = 127
9508pp_data->cap[194]->NotButton.PhysicalMin = 0
9509pp_data->cap[194]->NotButton.PhysicalMax = 0
9510pp_data->cap[194]->Units = 0
9511pp_data->cap[194]->UnitsExp = 0
9512
9513pp_data->cap[195]->UsagePage = 0xFF01
9514pp_data->cap[195]->ReportID = 0x81
9515pp_data->cap[195]->BitPosition = 0
9516pp_data->cap[195]->BitSize = 8
9517pp_data->cap[195]->ReportCount = 1
9518pp_data->cap[195]->BytePosition = 0x001A
9519pp_data->cap[195]->BitCount = 8
9520pp_data->cap[195]->BitField = 0x02
9521pp_data->cap[195]->NextBytePosition = 0x001B
9522pp_data->cap[195]->LinkCollection = 0x0004
9523pp_data->cap[195]->LinkUsagePage = 0xFF01
9524pp_data->cap[195]->LinkUsage = 0x0080
9525pp_data->cap[195]->IsMultipleItemsForArray = 0
9526pp_data->cap[195]->IsButtonCap = 0
9527pp_data->cap[195]->IsPadding = 0
9528pp_data->cap[195]->IsAbsolute = 1
9529pp_data->cap[195]->IsRange = 0
9530pp_data->cap[195]->IsAlias = 0
9531pp_data->cap[195]->IsStringRange = 0
9532pp_data->cap[195]->IsDesignatorRange = 0
9533pp_data->cap[195]->Reserved1 = 0x000000
9534pp_data->cap[195]->pp_cap->UnknownTokens[0].Token = 0x00
9535pp_data->cap[195]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9536pp_data->cap[195]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9537pp_data->cap[195]->pp_cap->UnknownTokens[1].Token = 0x00
9538pp_data->cap[195]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9539pp_data->cap[195]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9540pp_data->cap[195]->pp_cap->UnknownTokens[2].Token = 0x00
9541pp_data->cap[195]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9542pp_data->cap[195]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9543pp_data->cap[195]->pp_cap->UnknownTokens[3].Token = 0x00
9544pp_data->cap[195]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9545pp_data->cap[195]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9546pp_data->cap[195]->NotRange.Usage = 0x0081
9547pp_data->cap[195]->NotRange.Reserved1 = 0x0081
9548pp_data->cap[195]->NotRange.StringIndex = 0
9549pp_data->cap[195]->NotRange.Reserved2 = 0
9550pp_data->cap[195]->NotRange.DesignatorIndex = 0
9551pp_data->cap[195]->NotRange.Reserved3 = 0
9552pp_data->cap[195]->NotRange.DataIndex = 108
9553pp_data->cap[195]->NotRange.Reserved4 = 108
9554pp_data->cap[195]->NotButton.HasNull = 0
9555pp_data->cap[195]->NotButton.Reserved4 = 0x000000
9556pp_data->cap[195]->NotButton.LogicalMin = 0
9557pp_data->cap[195]->NotButton.LogicalMax = 127
9558pp_data->cap[195]->NotButton.PhysicalMin = 0
9559pp_data->cap[195]->NotButton.PhysicalMax = 0
9560pp_data->cap[195]->Units = 0
9561pp_data->cap[195]->UnitsExp = 0
9562
9563pp_data->cap[196]->UsagePage = 0xFF01
9564pp_data->cap[196]->ReportID = 0x81
9565pp_data->cap[196]->BitPosition = 0
9566pp_data->cap[196]->BitSize = 8
9567pp_data->cap[196]->ReportCount = 1
9568pp_data->cap[196]->BytePosition = 0x0019
9569pp_data->cap[196]->BitCount = 8
9570pp_data->cap[196]->BitField = 0x02
9571pp_data->cap[196]->NextBytePosition = 0x001A
9572pp_data->cap[196]->LinkCollection = 0x0004
9573pp_data->cap[196]->LinkUsagePage = 0xFF01
9574pp_data->cap[196]->LinkUsage = 0x0080
9575pp_data->cap[196]->IsMultipleItemsForArray = 0
9576pp_data->cap[196]->IsButtonCap = 0
9577pp_data->cap[196]->IsPadding = 0
9578pp_data->cap[196]->IsAbsolute = 1
9579pp_data->cap[196]->IsRange = 0
9580pp_data->cap[196]->IsAlias = 0
9581pp_data->cap[196]->IsStringRange = 0
9582pp_data->cap[196]->IsDesignatorRange = 0
9583pp_data->cap[196]->Reserved1 = 0x000000
9584pp_data->cap[196]->pp_cap->UnknownTokens[0].Token = 0x00
9585pp_data->cap[196]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9586pp_data->cap[196]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9587pp_data->cap[196]->pp_cap->UnknownTokens[1].Token = 0x00
9588pp_data->cap[196]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9589pp_data->cap[196]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9590pp_data->cap[196]->pp_cap->UnknownTokens[2].Token = 0x00
9591pp_data->cap[196]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9592pp_data->cap[196]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9593pp_data->cap[196]->pp_cap->UnknownTokens[3].Token = 0x00
9594pp_data->cap[196]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9595pp_data->cap[196]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9596pp_data->cap[196]->NotRange.Usage = 0x0081
9597pp_data->cap[196]->NotRange.Reserved1 = 0x0081
9598pp_data->cap[196]->NotRange.StringIndex = 0
9599pp_data->cap[196]->NotRange.Reserved2 = 0
9600pp_data->cap[196]->NotRange.DesignatorIndex = 0
9601pp_data->cap[196]->NotRange.Reserved3 = 0
9602pp_data->cap[196]->NotRange.DataIndex = 109
9603pp_data->cap[196]->NotRange.Reserved4 = 109
9604pp_data->cap[196]->NotButton.HasNull = 0
9605pp_data->cap[196]->NotButton.Reserved4 = 0x000000
9606pp_data->cap[196]->NotButton.LogicalMin = 0
9607pp_data->cap[196]->NotButton.LogicalMax = 127
9608pp_data->cap[196]->NotButton.PhysicalMin = 0
9609pp_data->cap[196]->NotButton.PhysicalMax = 0
9610pp_data->cap[196]->Units = 0
9611pp_data->cap[196]->UnitsExp = 0
9612
9613pp_data->cap[197]->UsagePage = 0xFF01
9614pp_data->cap[197]->ReportID = 0x81
9615pp_data->cap[197]->BitPosition = 0
9616pp_data->cap[197]->BitSize = 8
9617pp_data->cap[197]->ReportCount = 1
9618pp_data->cap[197]->BytePosition = 0x0018
9619pp_data->cap[197]->BitCount = 8
9620pp_data->cap[197]->BitField = 0x02
9621pp_data->cap[197]->NextBytePosition = 0x0019
9622pp_data->cap[197]->LinkCollection = 0x0004
9623pp_data->cap[197]->LinkUsagePage = 0xFF01
9624pp_data->cap[197]->LinkUsage = 0x0080
9625pp_data->cap[197]->IsMultipleItemsForArray = 0
9626pp_data->cap[197]->IsButtonCap = 0
9627pp_data->cap[197]->IsPadding = 0
9628pp_data->cap[197]->IsAbsolute = 1
9629pp_data->cap[197]->IsRange = 0
9630pp_data->cap[197]->IsAlias = 0
9631pp_data->cap[197]->IsStringRange = 0
9632pp_data->cap[197]->IsDesignatorRange = 0
9633pp_data->cap[197]->Reserved1 = 0x000000
9634pp_data->cap[197]->pp_cap->UnknownTokens[0].Token = 0x00
9635pp_data->cap[197]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9636pp_data->cap[197]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9637pp_data->cap[197]->pp_cap->UnknownTokens[1].Token = 0x00
9638pp_data->cap[197]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9639pp_data->cap[197]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9640pp_data->cap[197]->pp_cap->UnknownTokens[2].Token = 0x00
9641pp_data->cap[197]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9642pp_data->cap[197]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9643pp_data->cap[197]->pp_cap->UnknownTokens[3].Token = 0x00
9644pp_data->cap[197]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9645pp_data->cap[197]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9646pp_data->cap[197]->NotRange.Usage = 0x0081
9647pp_data->cap[197]->NotRange.Reserved1 = 0x0081
9648pp_data->cap[197]->NotRange.StringIndex = 0
9649pp_data->cap[197]->NotRange.Reserved2 = 0
9650pp_data->cap[197]->NotRange.DesignatorIndex = 0
9651pp_data->cap[197]->NotRange.Reserved3 = 0
9652pp_data->cap[197]->NotRange.DataIndex = 110
9653pp_data->cap[197]->NotRange.Reserved4 = 110
9654pp_data->cap[197]->NotButton.HasNull = 0
9655pp_data->cap[197]->NotButton.Reserved4 = 0x000000
9656pp_data->cap[197]->NotButton.LogicalMin = 0
9657pp_data->cap[197]->NotButton.LogicalMax = 127
9658pp_data->cap[197]->NotButton.PhysicalMin = 0
9659pp_data->cap[197]->NotButton.PhysicalMax = 0
9660pp_data->cap[197]->Units = 0
9661pp_data->cap[197]->UnitsExp = 0
9662
9663pp_data->cap[198]->UsagePage = 0xFF01
9664pp_data->cap[198]->ReportID = 0x81
9665pp_data->cap[198]->BitPosition = 0
9666pp_data->cap[198]->BitSize = 8
9667pp_data->cap[198]->ReportCount = 1
9668pp_data->cap[198]->BytePosition = 0x0017
9669pp_data->cap[198]->BitCount = 8
9670pp_data->cap[198]->BitField = 0x02
9671pp_data->cap[198]->NextBytePosition = 0x0018
9672pp_data->cap[198]->LinkCollection = 0x0004
9673pp_data->cap[198]->LinkUsagePage = 0xFF01
9674pp_data->cap[198]->LinkUsage = 0x0080
9675pp_data->cap[198]->IsMultipleItemsForArray = 0
9676pp_data->cap[198]->IsButtonCap = 0
9677pp_data->cap[198]->IsPadding = 0
9678pp_data->cap[198]->IsAbsolute = 1
9679pp_data->cap[198]->IsRange = 0
9680pp_data->cap[198]->IsAlias = 0
9681pp_data->cap[198]->IsStringRange = 0
9682pp_data->cap[198]->IsDesignatorRange = 0
9683pp_data->cap[198]->Reserved1 = 0x000000
9684pp_data->cap[198]->pp_cap->UnknownTokens[0].Token = 0x00
9685pp_data->cap[198]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9686pp_data->cap[198]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9687pp_data->cap[198]->pp_cap->UnknownTokens[1].Token = 0x00
9688pp_data->cap[198]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9689pp_data->cap[198]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9690pp_data->cap[198]->pp_cap->UnknownTokens[2].Token = 0x00
9691pp_data->cap[198]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9692pp_data->cap[198]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9693pp_data->cap[198]->pp_cap->UnknownTokens[3].Token = 0x00
9694pp_data->cap[198]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9695pp_data->cap[198]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9696pp_data->cap[198]->NotRange.Usage = 0x0081
9697pp_data->cap[198]->NotRange.Reserved1 = 0x0081
9698pp_data->cap[198]->NotRange.StringIndex = 0
9699pp_data->cap[198]->NotRange.Reserved2 = 0
9700pp_data->cap[198]->NotRange.DesignatorIndex = 0
9701pp_data->cap[198]->NotRange.Reserved3 = 0
9702pp_data->cap[198]->NotRange.DataIndex = 111
9703pp_data->cap[198]->NotRange.Reserved4 = 111
9704pp_data->cap[198]->NotButton.HasNull = 0
9705pp_data->cap[198]->NotButton.Reserved4 = 0x000000
9706pp_data->cap[198]->NotButton.LogicalMin = 0
9707pp_data->cap[198]->NotButton.LogicalMax = 127
9708pp_data->cap[198]->NotButton.PhysicalMin = 0
9709pp_data->cap[198]->NotButton.PhysicalMax = 0
9710pp_data->cap[198]->Units = 0
9711pp_data->cap[198]->UnitsExp = 0
9712
9713pp_data->cap[199]->UsagePage = 0xFF01
9714pp_data->cap[199]->ReportID = 0x81
9715pp_data->cap[199]->BitPosition = 0
9716pp_data->cap[199]->BitSize = 8
9717pp_data->cap[199]->ReportCount = 1
9718pp_data->cap[199]->BytePosition = 0x0016
9719pp_data->cap[199]->BitCount = 8
9720pp_data->cap[199]->BitField = 0x02
9721pp_data->cap[199]->NextBytePosition = 0x0017
9722pp_data->cap[199]->LinkCollection = 0x0004
9723pp_data->cap[199]->LinkUsagePage = 0xFF01
9724pp_data->cap[199]->LinkUsage = 0x0080
9725pp_data->cap[199]->IsMultipleItemsForArray = 0
9726pp_data->cap[199]->IsButtonCap = 0
9727pp_data->cap[199]->IsPadding = 0
9728pp_data->cap[199]->IsAbsolute = 1
9729pp_data->cap[199]->IsRange = 0
9730pp_data->cap[199]->IsAlias = 0
9731pp_data->cap[199]->IsStringRange = 0
9732pp_data->cap[199]->IsDesignatorRange = 0
9733pp_data->cap[199]->Reserved1 = 0x000000
9734pp_data->cap[199]->pp_cap->UnknownTokens[0].Token = 0x00
9735pp_data->cap[199]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9736pp_data->cap[199]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9737pp_data->cap[199]->pp_cap->UnknownTokens[1].Token = 0x00
9738pp_data->cap[199]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9739pp_data->cap[199]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9740pp_data->cap[199]->pp_cap->UnknownTokens[2].Token = 0x00
9741pp_data->cap[199]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9742pp_data->cap[199]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9743pp_data->cap[199]->pp_cap->UnknownTokens[3].Token = 0x00
9744pp_data->cap[199]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9745pp_data->cap[199]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9746pp_data->cap[199]->NotRange.Usage = 0x0081
9747pp_data->cap[199]->NotRange.Reserved1 = 0x0081
9748pp_data->cap[199]->NotRange.StringIndex = 0
9749pp_data->cap[199]->NotRange.Reserved2 = 0
9750pp_data->cap[199]->NotRange.DesignatorIndex = 0
9751pp_data->cap[199]->NotRange.Reserved3 = 0
9752pp_data->cap[199]->NotRange.DataIndex = 112
9753pp_data->cap[199]->NotRange.Reserved4 = 112
9754pp_data->cap[199]->NotButton.HasNull = 0
9755pp_data->cap[199]->NotButton.Reserved4 = 0x000000
9756pp_data->cap[199]->NotButton.LogicalMin = 0
9757pp_data->cap[199]->NotButton.LogicalMax = 127
9758pp_data->cap[199]->NotButton.PhysicalMin = 0
9759pp_data->cap[199]->NotButton.PhysicalMax = 0
9760pp_data->cap[199]->Units = 0
9761pp_data->cap[199]->UnitsExp = 0
9762
9763pp_data->cap[200]->UsagePage = 0xFF01
9764pp_data->cap[200]->ReportID = 0x81
9765pp_data->cap[200]->BitPosition = 0
9766pp_data->cap[200]->BitSize = 8
9767pp_data->cap[200]->ReportCount = 1
9768pp_data->cap[200]->BytePosition = 0x0015
9769pp_data->cap[200]->BitCount = 8
9770pp_data->cap[200]->BitField = 0x02
9771pp_data->cap[200]->NextBytePosition = 0x0016
9772pp_data->cap[200]->LinkCollection = 0x0004
9773pp_data->cap[200]->LinkUsagePage = 0xFF01
9774pp_data->cap[200]->LinkUsage = 0x0080
9775pp_data->cap[200]->IsMultipleItemsForArray = 0
9776pp_data->cap[200]->IsButtonCap = 0
9777pp_data->cap[200]->IsPadding = 0
9778pp_data->cap[200]->IsAbsolute = 1
9779pp_data->cap[200]->IsRange = 0
9780pp_data->cap[200]->IsAlias = 0
9781pp_data->cap[200]->IsStringRange = 0
9782pp_data->cap[200]->IsDesignatorRange = 0
9783pp_data->cap[200]->Reserved1 = 0x000000
9784pp_data->cap[200]->pp_cap->UnknownTokens[0].Token = 0x00
9785pp_data->cap[200]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9786pp_data->cap[200]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9787pp_data->cap[200]->pp_cap->UnknownTokens[1].Token = 0x00
9788pp_data->cap[200]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9789pp_data->cap[200]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9790pp_data->cap[200]->pp_cap->UnknownTokens[2].Token = 0x00
9791pp_data->cap[200]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9792pp_data->cap[200]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9793pp_data->cap[200]->pp_cap->UnknownTokens[3].Token = 0x00
9794pp_data->cap[200]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9795pp_data->cap[200]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9796pp_data->cap[200]->NotRange.Usage = 0x0081
9797pp_data->cap[200]->NotRange.Reserved1 = 0x0081
9798pp_data->cap[200]->NotRange.StringIndex = 0
9799pp_data->cap[200]->NotRange.Reserved2 = 0
9800pp_data->cap[200]->NotRange.DesignatorIndex = 0
9801pp_data->cap[200]->NotRange.Reserved3 = 0
9802pp_data->cap[200]->NotRange.DataIndex = 113
9803pp_data->cap[200]->NotRange.Reserved4 = 113
9804pp_data->cap[200]->NotButton.HasNull = 0
9805pp_data->cap[200]->NotButton.Reserved4 = 0x000000
9806pp_data->cap[200]->NotButton.LogicalMin = 0
9807pp_data->cap[200]->NotButton.LogicalMax = 127
9808pp_data->cap[200]->NotButton.PhysicalMin = 0
9809pp_data->cap[200]->NotButton.PhysicalMax = 0
9810pp_data->cap[200]->Units = 0
9811pp_data->cap[200]->UnitsExp = 0
9812
9813pp_data->cap[201]->UsagePage = 0xFF01
9814pp_data->cap[201]->ReportID = 0x81
9815pp_data->cap[201]->BitPosition = 0
9816pp_data->cap[201]->BitSize = 8
9817pp_data->cap[201]->ReportCount = 1
9818pp_data->cap[201]->BytePosition = 0x0014
9819pp_data->cap[201]->BitCount = 8
9820pp_data->cap[201]->BitField = 0x02
9821pp_data->cap[201]->NextBytePosition = 0x0015
9822pp_data->cap[201]->LinkCollection = 0x0004
9823pp_data->cap[201]->LinkUsagePage = 0xFF01
9824pp_data->cap[201]->LinkUsage = 0x0080
9825pp_data->cap[201]->IsMultipleItemsForArray = 0
9826pp_data->cap[201]->IsButtonCap = 0
9827pp_data->cap[201]->IsPadding = 0
9828pp_data->cap[201]->IsAbsolute = 1
9829pp_data->cap[201]->IsRange = 0
9830pp_data->cap[201]->IsAlias = 0
9831pp_data->cap[201]->IsStringRange = 0
9832pp_data->cap[201]->IsDesignatorRange = 0
9833pp_data->cap[201]->Reserved1 = 0x000000
9834pp_data->cap[201]->pp_cap->UnknownTokens[0].Token = 0x00
9835pp_data->cap[201]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9836pp_data->cap[201]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9837pp_data->cap[201]->pp_cap->UnknownTokens[1].Token = 0x00
9838pp_data->cap[201]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9839pp_data->cap[201]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9840pp_data->cap[201]->pp_cap->UnknownTokens[2].Token = 0x00
9841pp_data->cap[201]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9842pp_data->cap[201]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9843pp_data->cap[201]->pp_cap->UnknownTokens[3].Token = 0x00
9844pp_data->cap[201]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9845pp_data->cap[201]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9846pp_data->cap[201]->NotRange.Usage = 0x0081
9847pp_data->cap[201]->NotRange.Reserved1 = 0x0081
9848pp_data->cap[201]->NotRange.StringIndex = 0
9849pp_data->cap[201]->NotRange.Reserved2 = 0
9850pp_data->cap[201]->NotRange.DesignatorIndex = 0
9851pp_data->cap[201]->NotRange.Reserved3 = 0
9852pp_data->cap[201]->NotRange.DataIndex = 114
9853pp_data->cap[201]->NotRange.Reserved4 = 114
9854pp_data->cap[201]->NotButton.HasNull = 0
9855pp_data->cap[201]->NotButton.Reserved4 = 0x000000
9856pp_data->cap[201]->NotButton.LogicalMin = 0
9857pp_data->cap[201]->NotButton.LogicalMax = 127
9858pp_data->cap[201]->NotButton.PhysicalMin = 0
9859pp_data->cap[201]->NotButton.PhysicalMax = 0
9860pp_data->cap[201]->Units = 0
9861pp_data->cap[201]->UnitsExp = 0
9862
9863pp_data->cap[202]->UsagePage = 0xFF01
9864pp_data->cap[202]->ReportID = 0x81
9865pp_data->cap[202]->BitPosition = 0
9866pp_data->cap[202]->BitSize = 8
9867pp_data->cap[202]->ReportCount = 1
9868pp_data->cap[202]->BytePosition = 0x0013
9869pp_data->cap[202]->BitCount = 8
9870pp_data->cap[202]->BitField = 0x02
9871pp_data->cap[202]->NextBytePosition = 0x0014
9872pp_data->cap[202]->LinkCollection = 0x0004
9873pp_data->cap[202]->LinkUsagePage = 0xFF01
9874pp_data->cap[202]->LinkUsage = 0x0080
9875pp_data->cap[202]->IsMultipleItemsForArray = 0
9876pp_data->cap[202]->IsButtonCap = 0
9877pp_data->cap[202]->IsPadding = 0
9878pp_data->cap[202]->IsAbsolute = 1
9879pp_data->cap[202]->IsRange = 0
9880pp_data->cap[202]->IsAlias = 0
9881pp_data->cap[202]->IsStringRange = 0
9882pp_data->cap[202]->IsDesignatorRange = 0
9883pp_data->cap[202]->Reserved1 = 0x000000
9884pp_data->cap[202]->pp_cap->UnknownTokens[0].Token = 0x00
9885pp_data->cap[202]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9886pp_data->cap[202]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9887pp_data->cap[202]->pp_cap->UnknownTokens[1].Token = 0x00
9888pp_data->cap[202]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9889pp_data->cap[202]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9890pp_data->cap[202]->pp_cap->UnknownTokens[2].Token = 0x00
9891pp_data->cap[202]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9892pp_data->cap[202]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9893pp_data->cap[202]->pp_cap->UnknownTokens[3].Token = 0x00
9894pp_data->cap[202]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9895pp_data->cap[202]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9896pp_data->cap[202]->NotRange.Usage = 0x0081
9897pp_data->cap[202]->NotRange.Reserved1 = 0x0081
9898pp_data->cap[202]->NotRange.StringIndex = 0
9899pp_data->cap[202]->NotRange.Reserved2 = 0
9900pp_data->cap[202]->NotRange.DesignatorIndex = 0
9901pp_data->cap[202]->NotRange.Reserved3 = 0
9902pp_data->cap[202]->NotRange.DataIndex = 115
9903pp_data->cap[202]->NotRange.Reserved4 = 115
9904pp_data->cap[202]->NotButton.HasNull = 0
9905pp_data->cap[202]->NotButton.Reserved4 = 0x000000
9906pp_data->cap[202]->NotButton.LogicalMin = 0
9907pp_data->cap[202]->NotButton.LogicalMax = 127
9908pp_data->cap[202]->NotButton.PhysicalMin = 0
9909pp_data->cap[202]->NotButton.PhysicalMax = 0
9910pp_data->cap[202]->Units = 0
9911pp_data->cap[202]->UnitsExp = 0
9912
9913pp_data->cap[203]->UsagePage = 0xFF01
9914pp_data->cap[203]->ReportID = 0x81
9915pp_data->cap[203]->BitPosition = 0
9916pp_data->cap[203]->BitSize = 8
9917pp_data->cap[203]->ReportCount = 1
9918pp_data->cap[203]->BytePosition = 0x0012
9919pp_data->cap[203]->BitCount = 8
9920pp_data->cap[203]->BitField = 0x02
9921pp_data->cap[203]->NextBytePosition = 0x0013
9922pp_data->cap[203]->LinkCollection = 0x0004
9923pp_data->cap[203]->LinkUsagePage = 0xFF01
9924pp_data->cap[203]->LinkUsage = 0x0080
9925pp_data->cap[203]->IsMultipleItemsForArray = 0
9926pp_data->cap[203]->IsButtonCap = 0
9927pp_data->cap[203]->IsPadding = 0
9928pp_data->cap[203]->IsAbsolute = 1
9929pp_data->cap[203]->IsRange = 0
9930pp_data->cap[203]->IsAlias = 0
9931pp_data->cap[203]->IsStringRange = 0
9932pp_data->cap[203]->IsDesignatorRange = 0
9933pp_data->cap[203]->Reserved1 = 0x000000
9934pp_data->cap[203]->pp_cap->UnknownTokens[0].Token = 0x00
9935pp_data->cap[203]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9936pp_data->cap[203]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9937pp_data->cap[203]->pp_cap->UnknownTokens[1].Token = 0x00
9938pp_data->cap[203]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9939pp_data->cap[203]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9940pp_data->cap[203]->pp_cap->UnknownTokens[2].Token = 0x00
9941pp_data->cap[203]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9942pp_data->cap[203]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9943pp_data->cap[203]->pp_cap->UnknownTokens[3].Token = 0x00
9944pp_data->cap[203]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9945pp_data->cap[203]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9946pp_data->cap[203]->NotRange.Usage = 0x0081
9947pp_data->cap[203]->NotRange.Reserved1 = 0x0081
9948pp_data->cap[203]->NotRange.StringIndex = 0
9949pp_data->cap[203]->NotRange.Reserved2 = 0
9950pp_data->cap[203]->NotRange.DesignatorIndex = 0
9951pp_data->cap[203]->NotRange.Reserved3 = 0
9952pp_data->cap[203]->NotRange.DataIndex = 116
9953pp_data->cap[203]->NotRange.Reserved4 = 116
9954pp_data->cap[203]->NotButton.HasNull = 0
9955pp_data->cap[203]->NotButton.Reserved4 = 0x000000
9956pp_data->cap[203]->NotButton.LogicalMin = 0
9957pp_data->cap[203]->NotButton.LogicalMax = 127
9958pp_data->cap[203]->NotButton.PhysicalMin = 0
9959pp_data->cap[203]->NotButton.PhysicalMax = 0
9960pp_data->cap[203]->Units = 0
9961pp_data->cap[203]->UnitsExp = 0
9962
9963pp_data->cap[204]->UsagePage = 0xFF01
9964pp_data->cap[204]->ReportID = 0x81
9965pp_data->cap[204]->BitPosition = 0
9966pp_data->cap[204]->BitSize = 8
9967pp_data->cap[204]->ReportCount = 1
9968pp_data->cap[204]->BytePosition = 0x0011
9969pp_data->cap[204]->BitCount = 8
9970pp_data->cap[204]->BitField = 0x02
9971pp_data->cap[204]->NextBytePosition = 0x0012
9972pp_data->cap[204]->LinkCollection = 0x0004
9973pp_data->cap[204]->LinkUsagePage = 0xFF01
9974pp_data->cap[204]->LinkUsage = 0x0080
9975pp_data->cap[204]->IsMultipleItemsForArray = 0
9976pp_data->cap[204]->IsButtonCap = 0
9977pp_data->cap[204]->IsPadding = 0
9978pp_data->cap[204]->IsAbsolute = 1
9979pp_data->cap[204]->IsRange = 0
9980pp_data->cap[204]->IsAlias = 0
9981pp_data->cap[204]->IsStringRange = 0
9982pp_data->cap[204]->IsDesignatorRange = 0
9983pp_data->cap[204]->Reserved1 = 0x000000
9984pp_data->cap[204]->pp_cap->UnknownTokens[0].Token = 0x00
9985pp_data->cap[204]->pp_cap->UnknownTokens[0].Reserved = 0x000000
9986pp_data->cap[204]->pp_cap->UnknownTokens[0].BitField = 0x00000000
9987pp_data->cap[204]->pp_cap->UnknownTokens[1].Token = 0x00
9988pp_data->cap[204]->pp_cap->UnknownTokens[1].Reserved = 0x000000
9989pp_data->cap[204]->pp_cap->UnknownTokens[1].BitField = 0x00000000
9990pp_data->cap[204]->pp_cap->UnknownTokens[2].Token = 0x00
9991pp_data->cap[204]->pp_cap->UnknownTokens[2].Reserved = 0x000000
9992pp_data->cap[204]->pp_cap->UnknownTokens[2].BitField = 0x00000000
9993pp_data->cap[204]->pp_cap->UnknownTokens[3].Token = 0x00
9994pp_data->cap[204]->pp_cap->UnknownTokens[3].Reserved = 0x000000
9995pp_data->cap[204]->pp_cap->UnknownTokens[3].BitField = 0x00000000
9996pp_data->cap[204]->NotRange.Usage = 0x0081
9997pp_data->cap[204]->NotRange.Reserved1 = 0x0081
9998pp_data->cap[204]->NotRange.StringIndex = 0
9999pp_data->cap[204]->NotRange.Reserved2 = 0
10000pp_data->cap[204]->NotRange.DesignatorIndex = 0
10001pp_data->cap[204]->NotRange.Reserved3 = 0
10002pp_data->cap[204]->NotRange.DataIndex = 117
10003pp_data->cap[204]->NotRange.Reserved4 = 117
10004pp_data->cap[204]->NotButton.HasNull = 0
10005pp_data->cap[204]->NotButton.Reserved4 = 0x000000
10006pp_data->cap[204]->NotButton.LogicalMin = 0
10007pp_data->cap[204]->NotButton.LogicalMax = 127
10008pp_data->cap[204]->NotButton.PhysicalMin = 0
10009pp_data->cap[204]->NotButton.PhysicalMax = 0
10010pp_data->cap[204]->Units = 0
10011pp_data->cap[204]->UnitsExp = 0
10012
10013pp_data->cap[205]->UsagePage = 0xFF01
10014pp_data->cap[205]->ReportID = 0x81
10015pp_data->cap[205]->BitPosition = 0
10016pp_data->cap[205]->BitSize = 8
10017pp_data->cap[205]->ReportCount = 1
10018pp_data->cap[205]->BytePosition = 0x0010
10019pp_data->cap[205]->BitCount = 8
10020pp_data->cap[205]->BitField = 0x02
10021pp_data->cap[205]->NextBytePosition = 0x0011
10022pp_data->cap[205]->LinkCollection = 0x0004
10023pp_data->cap[205]->LinkUsagePage = 0xFF01
10024pp_data->cap[205]->LinkUsage = 0x0080
10025pp_data->cap[205]->IsMultipleItemsForArray = 0
10026pp_data->cap[205]->IsButtonCap = 0
10027pp_data->cap[205]->IsPadding = 0
10028pp_data->cap[205]->IsAbsolute = 1
10029pp_data->cap[205]->IsRange = 0
10030pp_data->cap[205]->IsAlias = 0
10031pp_data->cap[205]->IsStringRange = 0
10032pp_data->cap[205]->IsDesignatorRange = 0
10033pp_data->cap[205]->Reserved1 = 0x000000
10034pp_data->cap[205]->pp_cap->UnknownTokens[0].Token = 0x00
10035pp_data->cap[205]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10036pp_data->cap[205]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10037pp_data->cap[205]->pp_cap->UnknownTokens[1].Token = 0x00
10038pp_data->cap[205]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10039pp_data->cap[205]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10040pp_data->cap[205]->pp_cap->UnknownTokens[2].Token = 0x00
10041pp_data->cap[205]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10042pp_data->cap[205]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10043pp_data->cap[205]->pp_cap->UnknownTokens[3].Token = 0x00
10044pp_data->cap[205]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10045pp_data->cap[205]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10046pp_data->cap[205]->NotRange.Usage = 0x0081
10047pp_data->cap[205]->NotRange.Reserved1 = 0x0081
10048pp_data->cap[205]->NotRange.StringIndex = 0
10049pp_data->cap[205]->NotRange.Reserved2 = 0
10050pp_data->cap[205]->NotRange.DesignatorIndex = 0
10051pp_data->cap[205]->NotRange.Reserved3 = 0
10052pp_data->cap[205]->NotRange.DataIndex = 118
10053pp_data->cap[205]->NotRange.Reserved4 = 118
10054pp_data->cap[205]->NotButton.HasNull = 0
10055pp_data->cap[205]->NotButton.Reserved4 = 0x000000
10056pp_data->cap[205]->NotButton.LogicalMin = 0
10057pp_data->cap[205]->NotButton.LogicalMax = 127
10058pp_data->cap[205]->NotButton.PhysicalMin = 0
10059pp_data->cap[205]->NotButton.PhysicalMax = 0
10060pp_data->cap[205]->Units = 0
10061pp_data->cap[205]->UnitsExp = 0
10062
10063pp_data->cap[206]->UsagePage = 0xFF01
10064pp_data->cap[206]->ReportID = 0x81
10065pp_data->cap[206]->BitPosition = 0
10066pp_data->cap[206]->BitSize = 8
10067pp_data->cap[206]->ReportCount = 1
10068pp_data->cap[206]->BytePosition = 0x000F
10069pp_data->cap[206]->BitCount = 8
10070pp_data->cap[206]->BitField = 0x02
10071pp_data->cap[206]->NextBytePosition = 0x0010
10072pp_data->cap[206]->LinkCollection = 0x0004
10073pp_data->cap[206]->LinkUsagePage = 0xFF01
10074pp_data->cap[206]->LinkUsage = 0x0080
10075pp_data->cap[206]->IsMultipleItemsForArray = 0
10076pp_data->cap[206]->IsButtonCap = 0
10077pp_data->cap[206]->IsPadding = 0
10078pp_data->cap[206]->IsAbsolute = 1
10079pp_data->cap[206]->IsRange = 0
10080pp_data->cap[206]->IsAlias = 0
10081pp_data->cap[206]->IsStringRange = 0
10082pp_data->cap[206]->IsDesignatorRange = 0
10083pp_data->cap[206]->Reserved1 = 0x000000
10084pp_data->cap[206]->pp_cap->UnknownTokens[0].Token = 0x00
10085pp_data->cap[206]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10086pp_data->cap[206]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10087pp_data->cap[206]->pp_cap->UnknownTokens[1].Token = 0x00
10088pp_data->cap[206]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10089pp_data->cap[206]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10090pp_data->cap[206]->pp_cap->UnknownTokens[2].Token = 0x00
10091pp_data->cap[206]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10092pp_data->cap[206]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10093pp_data->cap[206]->pp_cap->UnknownTokens[3].Token = 0x00
10094pp_data->cap[206]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10095pp_data->cap[206]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10096pp_data->cap[206]->NotRange.Usage = 0x0081
10097pp_data->cap[206]->NotRange.Reserved1 = 0x0081
10098pp_data->cap[206]->NotRange.StringIndex = 0
10099pp_data->cap[206]->NotRange.Reserved2 = 0
10100pp_data->cap[206]->NotRange.DesignatorIndex = 0
10101pp_data->cap[206]->NotRange.Reserved3 = 0
10102pp_data->cap[206]->NotRange.DataIndex = 119
10103pp_data->cap[206]->NotRange.Reserved4 = 119
10104pp_data->cap[206]->NotButton.HasNull = 0
10105pp_data->cap[206]->NotButton.Reserved4 = 0x000000
10106pp_data->cap[206]->NotButton.LogicalMin = 0
10107pp_data->cap[206]->NotButton.LogicalMax = 127
10108pp_data->cap[206]->NotButton.PhysicalMin = 0
10109pp_data->cap[206]->NotButton.PhysicalMax = 0
10110pp_data->cap[206]->Units = 0
10111pp_data->cap[206]->UnitsExp = 0
10112
10113pp_data->cap[207]->UsagePage = 0xFF01
10114pp_data->cap[207]->ReportID = 0x81
10115pp_data->cap[207]->BitPosition = 0
10116pp_data->cap[207]->BitSize = 8
10117pp_data->cap[207]->ReportCount = 1
10118pp_data->cap[207]->BytePosition = 0x000E
10119pp_data->cap[207]->BitCount = 8
10120pp_data->cap[207]->BitField = 0x02
10121pp_data->cap[207]->NextBytePosition = 0x000F
10122pp_data->cap[207]->LinkCollection = 0x0004
10123pp_data->cap[207]->LinkUsagePage = 0xFF01
10124pp_data->cap[207]->LinkUsage = 0x0080
10125pp_data->cap[207]->IsMultipleItemsForArray = 0
10126pp_data->cap[207]->IsButtonCap = 0
10127pp_data->cap[207]->IsPadding = 0
10128pp_data->cap[207]->IsAbsolute = 1
10129pp_data->cap[207]->IsRange = 0
10130pp_data->cap[207]->IsAlias = 0
10131pp_data->cap[207]->IsStringRange = 0
10132pp_data->cap[207]->IsDesignatorRange = 0
10133pp_data->cap[207]->Reserved1 = 0x000000
10134pp_data->cap[207]->pp_cap->UnknownTokens[0].Token = 0x00
10135pp_data->cap[207]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10136pp_data->cap[207]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10137pp_data->cap[207]->pp_cap->UnknownTokens[1].Token = 0x00
10138pp_data->cap[207]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10139pp_data->cap[207]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10140pp_data->cap[207]->pp_cap->UnknownTokens[2].Token = 0x00
10141pp_data->cap[207]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10142pp_data->cap[207]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10143pp_data->cap[207]->pp_cap->UnknownTokens[3].Token = 0x00
10144pp_data->cap[207]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10145pp_data->cap[207]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10146pp_data->cap[207]->NotRange.Usage = 0x0081
10147pp_data->cap[207]->NotRange.Reserved1 = 0x0081
10148pp_data->cap[207]->NotRange.StringIndex = 0
10149pp_data->cap[207]->NotRange.Reserved2 = 0
10150pp_data->cap[207]->NotRange.DesignatorIndex = 0
10151pp_data->cap[207]->NotRange.Reserved3 = 0
10152pp_data->cap[207]->NotRange.DataIndex = 120
10153pp_data->cap[207]->NotRange.Reserved4 = 120
10154pp_data->cap[207]->NotButton.HasNull = 0
10155pp_data->cap[207]->NotButton.Reserved4 = 0x000000
10156pp_data->cap[207]->NotButton.LogicalMin = 0
10157pp_data->cap[207]->NotButton.LogicalMax = 127
10158pp_data->cap[207]->NotButton.PhysicalMin = 0
10159pp_data->cap[207]->NotButton.PhysicalMax = 0
10160pp_data->cap[207]->Units = 0
10161pp_data->cap[207]->UnitsExp = 0
10162
10163pp_data->cap[208]->UsagePage = 0xFF01
10164pp_data->cap[208]->ReportID = 0x81
10165pp_data->cap[208]->BitPosition = 0
10166pp_data->cap[208]->BitSize = 8
10167pp_data->cap[208]->ReportCount = 1
10168pp_data->cap[208]->BytePosition = 0x000D
10169pp_data->cap[208]->BitCount = 8
10170pp_data->cap[208]->BitField = 0x02
10171pp_data->cap[208]->NextBytePosition = 0x000E
10172pp_data->cap[208]->LinkCollection = 0x0004
10173pp_data->cap[208]->LinkUsagePage = 0xFF01
10174pp_data->cap[208]->LinkUsage = 0x0080
10175pp_data->cap[208]->IsMultipleItemsForArray = 0
10176pp_data->cap[208]->IsButtonCap = 0
10177pp_data->cap[208]->IsPadding = 0
10178pp_data->cap[208]->IsAbsolute = 1
10179pp_data->cap[208]->IsRange = 0
10180pp_data->cap[208]->IsAlias = 0
10181pp_data->cap[208]->IsStringRange = 0
10182pp_data->cap[208]->IsDesignatorRange = 0
10183pp_data->cap[208]->Reserved1 = 0x000000
10184pp_data->cap[208]->pp_cap->UnknownTokens[0].Token = 0x00
10185pp_data->cap[208]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10186pp_data->cap[208]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10187pp_data->cap[208]->pp_cap->UnknownTokens[1].Token = 0x00
10188pp_data->cap[208]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10189pp_data->cap[208]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10190pp_data->cap[208]->pp_cap->UnknownTokens[2].Token = 0x00
10191pp_data->cap[208]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10192pp_data->cap[208]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10193pp_data->cap[208]->pp_cap->UnknownTokens[3].Token = 0x00
10194pp_data->cap[208]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10195pp_data->cap[208]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10196pp_data->cap[208]->NotRange.Usage = 0x0081
10197pp_data->cap[208]->NotRange.Reserved1 = 0x0081
10198pp_data->cap[208]->NotRange.StringIndex = 0
10199pp_data->cap[208]->NotRange.Reserved2 = 0
10200pp_data->cap[208]->NotRange.DesignatorIndex = 0
10201pp_data->cap[208]->NotRange.Reserved3 = 0
10202pp_data->cap[208]->NotRange.DataIndex = 121
10203pp_data->cap[208]->NotRange.Reserved4 = 121
10204pp_data->cap[208]->NotButton.HasNull = 0
10205pp_data->cap[208]->NotButton.Reserved4 = 0x000000
10206pp_data->cap[208]->NotButton.LogicalMin = 0
10207pp_data->cap[208]->NotButton.LogicalMax = 127
10208pp_data->cap[208]->NotButton.PhysicalMin = 0
10209pp_data->cap[208]->NotButton.PhysicalMax = 0
10210pp_data->cap[208]->Units = 0
10211pp_data->cap[208]->UnitsExp = 0
10212
10213pp_data->cap[209]->UsagePage = 0xFF01
10214pp_data->cap[209]->ReportID = 0x81
10215pp_data->cap[209]->BitPosition = 0
10216pp_data->cap[209]->BitSize = 8
10217pp_data->cap[209]->ReportCount = 1
10218pp_data->cap[209]->BytePosition = 0x000C
10219pp_data->cap[209]->BitCount = 8
10220pp_data->cap[209]->BitField = 0x02
10221pp_data->cap[209]->NextBytePosition = 0x000D
10222pp_data->cap[209]->LinkCollection = 0x0004
10223pp_data->cap[209]->LinkUsagePage = 0xFF01
10224pp_data->cap[209]->LinkUsage = 0x0080
10225pp_data->cap[209]->IsMultipleItemsForArray = 0
10226pp_data->cap[209]->IsButtonCap = 0
10227pp_data->cap[209]->IsPadding = 0
10228pp_data->cap[209]->IsAbsolute = 1
10229pp_data->cap[209]->IsRange = 0
10230pp_data->cap[209]->IsAlias = 0
10231pp_data->cap[209]->IsStringRange = 0
10232pp_data->cap[209]->IsDesignatorRange = 0
10233pp_data->cap[209]->Reserved1 = 0x000000
10234pp_data->cap[209]->pp_cap->UnknownTokens[0].Token = 0x00
10235pp_data->cap[209]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10236pp_data->cap[209]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10237pp_data->cap[209]->pp_cap->UnknownTokens[1].Token = 0x00
10238pp_data->cap[209]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10239pp_data->cap[209]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10240pp_data->cap[209]->pp_cap->UnknownTokens[2].Token = 0x00
10241pp_data->cap[209]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10242pp_data->cap[209]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10243pp_data->cap[209]->pp_cap->UnknownTokens[3].Token = 0x00
10244pp_data->cap[209]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10245pp_data->cap[209]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10246pp_data->cap[209]->NotRange.Usage = 0x0081
10247pp_data->cap[209]->NotRange.Reserved1 = 0x0081
10248pp_data->cap[209]->NotRange.StringIndex = 0
10249pp_data->cap[209]->NotRange.Reserved2 = 0
10250pp_data->cap[209]->NotRange.DesignatorIndex = 0
10251pp_data->cap[209]->NotRange.Reserved3 = 0
10252pp_data->cap[209]->NotRange.DataIndex = 122
10253pp_data->cap[209]->NotRange.Reserved4 = 122
10254pp_data->cap[209]->NotButton.HasNull = 0
10255pp_data->cap[209]->NotButton.Reserved4 = 0x000000
10256pp_data->cap[209]->NotButton.LogicalMin = 0
10257pp_data->cap[209]->NotButton.LogicalMax = 127
10258pp_data->cap[209]->NotButton.PhysicalMin = 0
10259pp_data->cap[209]->NotButton.PhysicalMax = 0
10260pp_data->cap[209]->Units = 0
10261pp_data->cap[209]->UnitsExp = 0
10262
10263pp_data->cap[210]->UsagePage = 0xFF01
10264pp_data->cap[210]->ReportID = 0x81
10265pp_data->cap[210]->BitPosition = 0
10266pp_data->cap[210]->BitSize = 8
10267pp_data->cap[210]->ReportCount = 1
10268pp_data->cap[210]->BytePosition = 0x000B
10269pp_data->cap[210]->BitCount = 8
10270pp_data->cap[210]->BitField = 0x02
10271pp_data->cap[210]->NextBytePosition = 0x000C
10272pp_data->cap[210]->LinkCollection = 0x0004
10273pp_data->cap[210]->LinkUsagePage = 0xFF01
10274pp_data->cap[210]->LinkUsage = 0x0080
10275pp_data->cap[210]->IsMultipleItemsForArray = 0
10276pp_data->cap[210]->IsButtonCap = 0
10277pp_data->cap[210]->IsPadding = 0
10278pp_data->cap[210]->IsAbsolute = 1
10279pp_data->cap[210]->IsRange = 0
10280pp_data->cap[210]->IsAlias = 0
10281pp_data->cap[210]->IsStringRange = 0
10282pp_data->cap[210]->IsDesignatorRange = 0
10283pp_data->cap[210]->Reserved1 = 0x000000
10284pp_data->cap[210]->pp_cap->UnknownTokens[0].Token = 0x00
10285pp_data->cap[210]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10286pp_data->cap[210]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10287pp_data->cap[210]->pp_cap->UnknownTokens[1].Token = 0x00
10288pp_data->cap[210]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10289pp_data->cap[210]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10290pp_data->cap[210]->pp_cap->UnknownTokens[2].Token = 0x00
10291pp_data->cap[210]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10292pp_data->cap[210]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10293pp_data->cap[210]->pp_cap->UnknownTokens[3].Token = 0x00
10294pp_data->cap[210]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10295pp_data->cap[210]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10296pp_data->cap[210]->NotRange.Usage = 0x0081
10297pp_data->cap[210]->NotRange.Reserved1 = 0x0081
10298pp_data->cap[210]->NotRange.StringIndex = 0
10299pp_data->cap[210]->NotRange.Reserved2 = 0
10300pp_data->cap[210]->NotRange.DesignatorIndex = 0
10301pp_data->cap[210]->NotRange.Reserved3 = 0
10302pp_data->cap[210]->NotRange.DataIndex = 123
10303pp_data->cap[210]->NotRange.Reserved4 = 123
10304pp_data->cap[210]->NotButton.HasNull = 0
10305pp_data->cap[210]->NotButton.Reserved4 = 0x000000
10306pp_data->cap[210]->NotButton.LogicalMin = 0
10307pp_data->cap[210]->NotButton.LogicalMax = 127
10308pp_data->cap[210]->NotButton.PhysicalMin = 0
10309pp_data->cap[210]->NotButton.PhysicalMax = 0
10310pp_data->cap[210]->Units = 0
10311pp_data->cap[210]->UnitsExp = 0
10312
10313pp_data->cap[211]->UsagePage = 0xFF01
10314pp_data->cap[211]->ReportID = 0x81
10315pp_data->cap[211]->BitPosition = 0
10316pp_data->cap[211]->BitSize = 8
10317pp_data->cap[211]->ReportCount = 1
10318pp_data->cap[211]->BytePosition = 0x000A
10319pp_data->cap[211]->BitCount = 8
10320pp_data->cap[211]->BitField = 0x02
10321pp_data->cap[211]->NextBytePosition = 0x000B
10322pp_data->cap[211]->LinkCollection = 0x0004
10323pp_data->cap[211]->LinkUsagePage = 0xFF01
10324pp_data->cap[211]->LinkUsage = 0x0080
10325pp_data->cap[211]->IsMultipleItemsForArray = 0
10326pp_data->cap[211]->IsButtonCap = 0
10327pp_data->cap[211]->IsPadding = 0
10328pp_data->cap[211]->IsAbsolute = 1
10329pp_data->cap[211]->IsRange = 0
10330pp_data->cap[211]->IsAlias = 0
10331pp_data->cap[211]->IsStringRange = 0
10332pp_data->cap[211]->IsDesignatorRange = 0
10333pp_data->cap[211]->Reserved1 = 0x000000
10334pp_data->cap[211]->pp_cap->UnknownTokens[0].Token = 0x00
10335pp_data->cap[211]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10336pp_data->cap[211]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10337pp_data->cap[211]->pp_cap->UnknownTokens[1].Token = 0x00
10338pp_data->cap[211]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10339pp_data->cap[211]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10340pp_data->cap[211]->pp_cap->UnknownTokens[2].Token = 0x00
10341pp_data->cap[211]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10342pp_data->cap[211]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10343pp_data->cap[211]->pp_cap->UnknownTokens[3].Token = 0x00
10344pp_data->cap[211]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10345pp_data->cap[211]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10346pp_data->cap[211]->NotRange.Usage = 0x0081
10347pp_data->cap[211]->NotRange.Reserved1 = 0x0081
10348pp_data->cap[211]->NotRange.StringIndex = 0
10349pp_data->cap[211]->NotRange.Reserved2 = 0
10350pp_data->cap[211]->NotRange.DesignatorIndex = 0
10351pp_data->cap[211]->NotRange.Reserved3 = 0
10352pp_data->cap[211]->NotRange.DataIndex = 124
10353pp_data->cap[211]->NotRange.Reserved4 = 124
10354pp_data->cap[211]->NotButton.HasNull = 0
10355pp_data->cap[211]->NotButton.Reserved4 = 0x000000
10356pp_data->cap[211]->NotButton.LogicalMin = 0
10357pp_data->cap[211]->NotButton.LogicalMax = 127
10358pp_data->cap[211]->NotButton.PhysicalMin = 0
10359pp_data->cap[211]->NotButton.PhysicalMax = 0
10360pp_data->cap[211]->Units = 0
10361pp_data->cap[211]->UnitsExp = 0
10362
10363pp_data->cap[212]->UsagePage = 0xFF01
10364pp_data->cap[212]->ReportID = 0x81
10365pp_data->cap[212]->BitPosition = 0
10366pp_data->cap[212]->BitSize = 8
10367pp_data->cap[212]->ReportCount = 1
10368pp_data->cap[212]->BytePosition = 0x0009
10369pp_data->cap[212]->BitCount = 8
10370pp_data->cap[212]->BitField = 0x02
10371pp_data->cap[212]->NextBytePosition = 0x000A
10372pp_data->cap[212]->LinkCollection = 0x0004
10373pp_data->cap[212]->LinkUsagePage = 0xFF01
10374pp_data->cap[212]->LinkUsage = 0x0080
10375pp_data->cap[212]->IsMultipleItemsForArray = 0
10376pp_data->cap[212]->IsButtonCap = 0
10377pp_data->cap[212]->IsPadding = 0
10378pp_data->cap[212]->IsAbsolute = 1
10379pp_data->cap[212]->IsRange = 0
10380pp_data->cap[212]->IsAlias = 0
10381pp_data->cap[212]->IsStringRange = 0
10382pp_data->cap[212]->IsDesignatorRange = 0
10383pp_data->cap[212]->Reserved1 = 0x000000
10384pp_data->cap[212]->pp_cap->UnknownTokens[0].Token = 0x00
10385pp_data->cap[212]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10386pp_data->cap[212]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10387pp_data->cap[212]->pp_cap->UnknownTokens[1].Token = 0x00
10388pp_data->cap[212]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10389pp_data->cap[212]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10390pp_data->cap[212]->pp_cap->UnknownTokens[2].Token = 0x00
10391pp_data->cap[212]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10392pp_data->cap[212]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10393pp_data->cap[212]->pp_cap->UnknownTokens[3].Token = 0x00
10394pp_data->cap[212]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10395pp_data->cap[212]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10396pp_data->cap[212]->NotRange.Usage = 0x0081
10397pp_data->cap[212]->NotRange.Reserved1 = 0x0081
10398pp_data->cap[212]->NotRange.StringIndex = 0
10399pp_data->cap[212]->NotRange.Reserved2 = 0
10400pp_data->cap[212]->NotRange.DesignatorIndex = 0
10401pp_data->cap[212]->NotRange.Reserved3 = 0
10402pp_data->cap[212]->NotRange.DataIndex = 125
10403pp_data->cap[212]->NotRange.Reserved4 = 125
10404pp_data->cap[212]->NotButton.HasNull = 0
10405pp_data->cap[212]->NotButton.Reserved4 = 0x000000
10406pp_data->cap[212]->NotButton.LogicalMin = 0
10407pp_data->cap[212]->NotButton.LogicalMax = 127
10408pp_data->cap[212]->NotButton.PhysicalMin = 0
10409pp_data->cap[212]->NotButton.PhysicalMax = 0
10410pp_data->cap[212]->Units = 0
10411pp_data->cap[212]->UnitsExp = 0
10412
10413pp_data->cap[213]->UsagePage = 0xFF01
10414pp_data->cap[213]->ReportID = 0x81
10415pp_data->cap[213]->BitPosition = 0
10416pp_data->cap[213]->BitSize = 8
10417pp_data->cap[213]->ReportCount = 1
10418pp_data->cap[213]->BytePosition = 0x0008
10419pp_data->cap[213]->BitCount = 8
10420pp_data->cap[213]->BitField = 0x02
10421pp_data->cap[213]->NextBytePosition = 0x0009
10422pp_data->cap[213]->LinkCollection = 0x0004
10423pp_data->cap[213]->LinkUsagePage = 0xFF01
10424pp_data->cap[213]->LinkUsage = 0x0080
10425pp_data->cap[213]->IsMultipleItemsForArray = 0
10426pp_data->cap[213]->IsButtonCap = 0
10427pp_data->cap[213]->IsPadding = 0
10428pp_data->cap[213]->IsAbsolute = 1
10429pp_data->cap[213]->IsRange = 0
10430pp_data->cap[213]->IsAlias = 0
10431pp_data->cap[213]->IsStringRange = 0
10432pp_data->cap[213]->IsDesignatorRange = 0
10433pp_data->cap[213]->Reserved1 = 0x000000
10434pp_data->cap[213]->pp_cap->UnknownTokens[0].Token = 0x00
10435pp_data->cap[213]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10436pp_data->cap[213]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10437pp_data->cap[213]->pp_cap->UnknownTokens[1].Token = 0x00
10438pp_data->cap[213]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10439pp_data->cap[213]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10440pp_data->cap[213]->pp_cap->UnknownTokens[2].Token = 0x00
10441pp_data->cap[213]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10442pp_data->cap[213]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10443pp_data->cap[213]->pp_cap->UnknownTokens[3].Token = 0x00
10444pp_data->cap[213]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10445pp_data->cap[213]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10446pp_data->cap[213]->NotRange.Usage = 0x0081
10447pp_data->cap[213]->NotRange.Reserved1 = 0x0081
10448pp_data->cap[213]->NotRange.StringIndex = 0
10449pp_data->cap[213]->NotRange.Reserved2 = 0
10450pp_data->cap[213]->NotRange.DesignatorIndex = 0
10451pp_data->cap[213]->NotRange.Reserved3 = 0
10452pp_data->cap[213]->NotRange.DataIndex = 126
10453pp_data->cap[213]->NotRange.Reserved4 = 126
10454pp_data->cap[213]->NotButton.HasNull = 0
10455pp_data->cap[213]->NotButton.Reserved4 = 0x000000
10456pp_data->cap[213]->NotButton.LogicalMin = 0
10457pp_data->cap[213]->NotButton.LogicalMax = 127
10458pp_data->cap[213]->NotButton.PhysicalMin = 0
10459pp_data->cap[213]->NotButton.PhysicalMax = 0
10460pp_data->cap[213]->Units = 0
10461pp_data->cap[213]->UnitsExp = 0
10462
10463pp_data->cap[214]->UsagePage = 0xFF01
10464pp_data->cap[214]->ReportID = 0x81
10465pp_data->cap[214]->BitPosition = 0
10466pp_data->cap[214]->BitSize = 8
10467pp_data->cap[214]->ReportCount = 1
10468pp_data->cap[214]->BytePosition = 0x0007
10469pp_data->cap[214]->BitCount = 8
10470pp_data->cap[214]->BitField = 0x02
10471pp_data->cap[214]->NextBytePosition = 0x0008
10472pp_data->cap[214]->LinkCollection = 0x0004
10473pp_data->cap[214]->LinkUsagePage = 0xFF01
10474pp_data->cap[214]->LinkUsage = 0x0080
10475pp_data->cap[214]->IsMultipleItemsForArray = 0
10476pp_data->cap[214]->IsButtonCap = 0
10477pp_data->cap[214]->IsPadding = 0
10478pp_data->cap[214]->IsAbsolute = 1
10479pp_data->cap[214]->IsRange = 0
10480pp_data->cap[214]->IsAlias = 0
10481pp_data->cap[214]->IsStringRange = 0
10482pp_data->cap[214]->IsDesignatorRange = 0
10483pp_data->cap[214]->Reserved1 = 0x000000
10484pp_data->cap[214]->pp_cap->UnknownTokens[0].Token = 0x00
10485pp_data->cap[214]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10486pp_data->cap[214]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10487pp_data->cap[214]->pp_cap->UnknownTokens[1].Token = 0x00
10488pp_data->cap[214]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10489pp_data->cap[214]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10490pp_data->cap[214]->pp_cap->UnknownTokens[2].Token = 0x00
10491pp_data->cap[214]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10492pp_data->cap[214]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10493pp_data->cap[214]->pp_cap->UnknownTokens[3].Token = 0x00
10494pp_data->cap[214]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10495pp_data->cap[214]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10496pp_data->cap[214]->NotRange.Usage = 0x0081
10497pp_data->cap[214]->NotRange.Reserved1 = 0x0081
10498pp_data->cap[214]->NotRange.StringIndex = 0
10499pp_data->cap[214]->NotRange.Reserved2 = 0
10500pp_data->cap[214]->NotRange.DesignatorIndex = 0
10501pp_data->cap[214]->NotRange.Reserved3 = 0
10502pp_data->cap[214]->NotRange.DataIndex = 127
10503pp_data->cap[214]->NotRange.Reserved4 = 127
10504pp_data->cap[214]->NotButton.HasNull = 0
10505pp_data->cap[214]->NotButton.Reserved4 = 0x000000
10506pp_data->cap[214]->NotButton.LogicalMin = 0
10507pp_data->cap[214]->NotButton.LogicalMax = 127
10508pp_data->cap[214]->NotButton.PhysicalMin = 0
10509pp_data->cap[214]->NotButton.PhysicalMax = 0
10510pp_data->cap[214]->Units = 0
10511pp_data->cap[214]->UnitsExp = 0
10512
10513pp_data->cap[215]->UsagePage = 0xFF01
10514pp_data->cap[215]->ReportID = 0x81
10515pp_data->cap[215]->BitPosition = 0
10516pp_data->cap[215]->BitSize = 8
10517pp_data->cap[215]->ReportCount = 1
10518pp_data->cap[215]->BytePosition = 0x0006
10519pp_data->cap[215]->BitCount = 8
10520pp_data->cap[215]->BitField = 0x02
10521pp_data->cap[215]->NextBytePosition = 0x0007
10522pp_data->cap[215]->LinkCollection = 0x0004
10523pp_data->cap[215]->LinkUsagePage = 0xFF01
10524pp_data->cap[215]->LinkUsage = 0x0080
10525pp_data->cap[215]->IsMultipleItemsForArray = 0
10526pp_data->cap[215]->IsButtonCap = 0
10527pp_data->cap[215]->IsPadding = 0
10528pp_data->cap[215]->IsAbsolute = 1
10529pp_data->cap[215]->IsRange = 0
10530pp_data->cap[215]->IsAlias = 0
10531pp_data->cap[215]->IsStringRange = 0
10532pp_data->cap[215]->IsDesignatorRange = 0
10533pp_data->cap[215]->Reserved1 = 0x000000
10534pp_data->cap[215]->pp_cap->UnknownTokens[0].Token = 0x00
10535pp_data->cap[215]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10536pp_data->cap[215]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10537pp_data->cap[215]->pp_cap->UnknownTokens[1].Token = 0x00
10538pp_data->cap[215]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10539pp_data->cap[215]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10540pp_data->cap[215]->pp_cap->UnknownTokens[2].Token = 0x00
10541pp_data->cap[215]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10542pp_data->cap[215]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10543pp_data->cap[215]->pp_cap->UnknownTokens[3].Token = 0x00
10544pp_data->cap[215]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10545pp_data->cap[215]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10546pp_data->cap[215]->NotRange.Usage = 0x0081
10547pp_data->cap[215]->NotRange.Reserved1 = 0x0081
10548pp_data->cap[215]->NotRange.StringIndex = 0
10549pp_data->cap[215]->NotRange.Reserved2 = 0
10550pp_data->cap[215]->NotRange.DesignatorIndex = 0
10551pp_data->cap[215]->NotRange.Reserved3 = 0
10552pp_data->cap[215]->NotRange.DataIndex = 128
10553pp_data->cap[215]->NotRange.Reserved4 = 128
10554pp_data->cap[215]->NotButton.HasNull = 0
10555pp_data->cap[215]->NotButton.Reserved4 = 0x000000
10556pp_data->cap[215]->NotButton.LogicalMin = 0
10557pp_data->cap[215]->NotButton.LogicalMax = 127
10558pp_data->cap[215]->NotButton.PhysicalMin = 0
10559pp_data->cap[215]->NotButton.PhysicalMax = 0
10560pp_data->cap[215]->Units = 0
10561pp_data->cap[215]->UnitsExp = 0
10562
10563pp_data->cap[216]->UsagePage = 0xFF01
10564pp_data->cap[216]->ReportID = 0x81
10565pp_data->cap[216]->BitPosition = 0
10566pp_data->cap[216]->BitSize = 8
10567pp_data->cap[216]->ReportCount = 1
10568pp_data->cap[216]->BytePosition = 0x0005
10569pp_data->cap[216]->BitCount = 8
10570pp_data->cap[216]->BitField = 0x02
10571pp_data->cap[216]->NextBytePosition = 0x0006
10572pp_data->cap[216]->LinkCollection = 0x0004
10573pp_data->cap[216]->LinkUsagePage = 0xFF01
10574pp_data->cap[216]->LinkUsage = 0x0080
10575pp_data->cap[216]->IsMultipleItemsForArray = 0
10576pp_data->cap[216]->IsButtonCap = 0
10577pp_data->cap[216]->IsPadding = 0
10578pp_data->cap[216]->IsAbsolute = 1
10579pp_data->cap[216]->IsRange = 0
10580pp_data->cap[216]->IsAlias = 0
10581pp_data->cap[216]->IsStringRange = 0
10582pp_data->cap[216]->IsDesignatorRange = 0
10583pp_data->cap[216]->Reserved1 = 0x000000
10584pp_data->cap[216]->pp_cap->UnknownTokens[0].Token = 0x00
10585pp_data->cap[216]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10586pp_data->cap[216]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10587pp_data->cap[216]->pp_cap->UnknownTokens[1].Token = 0x00
10588pp_data->cap[216]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10589pp_data->cap[216]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10590pp_data->cap[216]->pp_cap->UnknownTokens[2].Token = 0x00
10591pp_data->cap[216]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10592pp_data->cap[216]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10593pp_data->cap[216]->pp_cap->UnknownTokens[3].Token = 0x00
10594pp_data->cap[216]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10595pp_data->cap[216]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10596pp_data->cap[216]->NotRange.Usage = 0x0081
10597pp_data->cap[216]->NotRange.Reserved1 = 0x0081
10598pp_data->cap[216]->NotRange.StringIndex = 0
10599pp_data->cap[216]->NotRange.Reserved2 = 0
10600pp_data->cap[216]->NotRange.DesignatorIndex = 0
10601pp_data->cap[216]->NotRange.Reserved3 = 0
10602pp_data->cap[216]->NotRange.DataIndex = 129
10603pp_data->cap[216]->NotRange.Reserved4 = 129
10604pp_data->cap[216]->NotButton.HasNull = 0
10605pp_data->cap[216]->NotButton.Reserved4 = 0x000000
10606pp_data->cap[216]->NotButton.LogicalMin = 0
10607pp_data->cap[216]->NotButton.LogicalMax = 127
10608pp_data->cap[216]->NotButton.PhysicalMin = 0
10609pp_data->cap[216]->NotButton.PhysicalMax = 0
10610pp_data->cap[216]->Units = 0
10611pp_data->cap[216]->UnitsExp = 0
10612
10613pp_data->cap[217]->UsagePage = 0xFF01
10614pp_data->cap[217]->ReportID = 0x81
10615pp_data->cap[217]->BitPosition = 0
10616pp_data->cap[217]->BitSize = 8
10617pp_data->cap[217]->ReportCount = 1
10618pp_data->cap[217]->BytePosition = 0x0004
10619pp_data->cap[217]->BitCount = 8
10620pp_data->cap[217]->BitField = 0x02
10621pp_data->cap[217]->NextBytePosition = 0x0005
10622pp_data->cap[217]->LinkCollection = 0x0004
10623pp_data->cap[217]->LinkUsagePage = 0xFF01
10624pp_data->cap[217]->LinkUsage = 0x0080
10625pp_data->cap[217]->IsMultipleItemsForArray = 0
10626pp_data->cap[217]->IsButtonCap = 0
10627pp_data->cap[217]->IsPadding = 0
10628pp_data->cap[217]->IsAbsolute = 1
10629pp_data->cap[217]->IsRange = 0
10630pp_data->cap[217]->IsAlias = 0
10631pp_data->cap[217]->IsStringRange = 0
10632pp_data->cap[217]->IsDesignatorRange = 0
10633pp_data->cap[217]->Reserved1 = 0x000000
10634pp_data->cap[217]->pp_cap->UnknownTokens[0].Token = 0x00
10635pp_data->cap[217]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10636pp_data->cap[217]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10637pp_data->cap[217]->pp_cap->UnknownTokens[1].Token = 0x00
10638pp_data->cap[217]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10639pp_data->cap[217]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10640pp_data->cap[217]->pp_cap->UnknownTokens[2].Token = 0x00
10641pp_data->cap[217]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10642pp_data->cap[217]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10643pp_data->cap[217]->pp_cap->UnknownTokens[3].Token = 0x00
10644pp_data->cap[217]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10645pp_data->cap[217]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10646pp_data->cap[217]->NotRange.Usage = 0x0081
10647pp_data->cap[217]->NotRange.Reserved1 = 0x0081
10648pp_data->cap[217]->NotRange.StringIndex = 0
10649pp_data->cap[217]->NotRange.Reserved2 = 0
10650pp_data->cap[217]->NotRange.DesignatorIndex = 0
10651pp_data->cap[217]->NotRange.Reserved3 = 0
10652pp_data->cap[217]->NotRange.DataIndex = 130
10653pp_data->cap[217]->NotRange.Reserved4 = 130
10654pp_data->cap[217]->NotButton.HasNull = 0
10655pp_data->cap[217]->NotButton.Reserved4 = 0x000000
10656pp_data->cap[217]->NotButton.LogicalMin = 0
10657pp_data->cap[217]->NotButton.LogicalMax = 127
10658pp_data->cap[217]->NotButton.PhysicalMin = 0
10659pp_data->cap[217]->NotButton.PhysicalMax = 0
10660pp_data->cap[217]->Units = 0
10661pp_data->cap[217]->UnitsExp = 0
10662
10663pp_data->cap[218]->UsagePage = 0xFF01
10664pp_data->cap[218]->ReportID = 0x81
10665pp_data->cap[218]->BitPosition = 0
10666pp_data->cap[218]->BitSize = 8
10667pp_data->cap[218]->ReportCount = 1
10668pp_data->cap[218]->BytePosition = 0x0003
10669pp_data->cap[218]->BitCount = 8
10670pp_data->cap[218]->BitField = 0x02
10671pp_data->cap[218]->NextBytePosition = 0x0004
10672pp_data->cap[218]->LinkCollection = 0x0004
10673pp_data->cap[218]->LinkUsagePage = 0xFF01
10674pp_data->cap[218]->LinkUsage = 0x0080
10675pp_data->cap[218]->IsMultipleItemsForArray = 0
10676pp_data->cap[218]->IsButtonCap = 0
10677pp_data->cap[218]->IsPadding = 0
10678pp_data->cap[218]->IsAbsolute = 1
10679pp_data->cap[218]->IsRange = 0
10680pp_data->cap[218]->IsAlias = 0
10681pp_data->cap[218]->IsStringRange = 0
10682pp_data->cap[218]->IsDesignatorRange = 0
10683pp_data->cap[218]->Reserved1 = 0x000000
10684pp_data->cap[218]->pp_cap->UnknownTokens[0].Token = 0x00
10685pp_data->cap[218]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10686pp_data->cap[218]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10687pp_data->cap[218]->pp_cap->UnknownTokens[1].Token = 0x00
10688pp_data->cap[218]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10689pp_data->cap[218]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10690pp_data->cap[218]->pp_cap->UnknownTokens[2].Token = 0x00
10691pp_data->cap[218]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10692pp_data->cap[218]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10693pp_data->cap[218]->pp_cap->UnknownTokens[3].Token = 0x00
10694pp_data->cap[218]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10695pp_data->cap[218]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10696pp_data->cap[218]->NotRange.Usage = 0x0081
10697pp_data->cap[218]->NotRange.Reserved1 = 0x0081
10698pp_data->cap[218]->NotRange.StringIndex = 0
10699pp_data->cap[218]->NotRange.Reserved2 = 0
10700pp_data->cap[218]->NotRange.DesignatorIndex = 0
10701pp_data->cap[218]->NotRange.Reserved3 = 0
10702pp_data->cap[218]->NotRange.DataIndex = 131
10703pp_data->cap[218]->NotRange.Reserved4 = 131
10704pp_data->cap[218]->NotButton.HasNull = 0
10705pp_data->cap[218]->NotButton.Reserved4 = 0x000000
10706pp_data->cap[218]->NotButton.LogicalMin = 0
10707pp_data->cap[218]->NotButton.LogicalMax = 127
10708pp_data->cap[218]->NotButton.PhysicalMin = 0
10709pp_data->cap[218]->NotButton.PhysicalMax = 0
10710pp_data->cap[218]->Units = 0
10711pp_data->cap[218]->UnitsExp = 0
10712
10713pp_data->cap[219]->UsagePage = 0xFF01
10714pp_data->cap[219]->ReportID = 0x81
10715pp_data->cap[219]->BitPosition = 0
10716pp_data->cap[219]->BitSize = 8
10717pp_data->cap[219]->ReportCount = 1
10718pp_data->cap[219]->BytePosition = 0x0002
10719pp_data->cap[219]->BitCount = 8
10720pp_data->cap[219]->BitField = 0x02
10721pp_data->cap[219]->NextBytePosition = 0x0003
10722pp_data->cap[219]->LinkCollection = 0x0004
10723pp_data->cap[219]->LinkUsagePage = 0xFF01
10724pp_data->cap[219]->LinkUsage = 0x0080
10725pp_data->cap[219]->IsMultipleItemsForArray = 0
10726pp_data->cap[219]->IsButtonCap = 0
10727pp_data->cap[219]->IsPadding = 0
10728pp_data->cap[219]->IsAbsolute = 1
10729pp_data->cap[219]->IsRange = 0
10730pp_data->cap[219]->IsAlias = 0
10731pp_data->cap[219]->IsStringRange = 0
10732pp_data->cap[219]->IsDesignatorRange = 0
10733pp_data->cap[219]->Reserved1 = 0x000000
10734pp_data->cap[219]->pp_cap->UnknownTokens[0].Token = 0x00
10735pp_data->cap[219]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10736pp_data->cap[219]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10737pp_data->cap[219]->pp_cap->UnknownTokens[1].Token = 0x00
10738pp_data->cap[219]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10739pp_data->cap[219]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10740pp_data->cap[219]->pp_cap->UnknownTokens[2].Token = 0x00
10741pp_data->cap[219]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10742pp_data->cap[219]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10743pp_data->cap[219]->pp_cap->UnknownTokens[3].Token = 0x00
10744pp_data->cap[219]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10745pp_data->cap[219]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10746pp_data->cap[219]->NotRange.Usage = 0x0081
10747pp_data->cap[219]->NotRange.Reserved1 = 0x0081
10748pp_data->cap[219]->NotRange.StringIndex = 0
10749pp_data->cap[219]->NotRange.Reserved2 = 0
10750pp_data->cap[219]->NotRange.DesignatorIndex = 0
10751pp_data->cap[219]->NotRange.Reserved3 = 0
10752pp_data->cap[219]->NotRange.DataIndex = 132
10753pp_data->cap[219]->NotRange.Reserved4 = 132
10754pp_data->cap[219]->NotButton.HasNull = 0
10755pp_data->cap[219]->NotButton.Reserved4 = 0x000000
10756pp_data->cap[219]->NotButton.LogicalMin = 0
10757pp_data->cap[219]->NotButton.LogicalMax = 127
10758pp_data->cap[219]->NotButton.PhysicalMin = 0
10759pp_data->cap[219]->NotButton.PhysicalMax = 0
10760pp_data->cap[219]->Units = 0
10761pp_data->cap[219]->UnitsExp = 0
10762
10763pp_data->cap[220]->UsagePage = 0xFF01
10764pp_data->cap[220]->ReportID = 0x81
10765pp_data->cap[220]->BitPosition = 0
10766pp_data->cap[220]->BitSize = 8
10767pp_data->cap[220]->ReportCount = 1
10768pp_data->cap[220]->BytePosition = 0x0001
10769pp_data->cap[220]->BitCount = 8
10770pp_data->cap[220]->BitField = 0x02
10771pp_data->cap[220]->NextBytePosition = 0x0002
10772pp_data->cap[220]->LinkCollection = 0x0004
10773pp_data->cap[220]->LinkUsagePage = 0xFF01
10774pp_data->cap[220]->LinkUsage = 0x0080
10775pp_data->cap[220]->IsMultipleItemsForArray = 0
10776pp_data->cap[220]->IsButtonCap = 0
10777pp_data->cap[220]->IsPadding = 0
10778pp_data->cap[220]->IsAbsolute = 1
10779pp_data->cap[220]->IsRange = 0
10780pp_data->cap[220]->IsAlias = 0
10781pp_data->cap[220]->IsStringRange = 0
10782pp_data->cap[220]->IsDesignatorRange = 0
10783pp_data->cap[220]->Reserved1 = 0x000000
10784pp_data->cap[220]->pp_cap->UnknownTokens[0].Token = 0x00
10785pp_data->cap[220]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10786pp_data->cap[220]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10787pp_data->cap[220]->pp_cap->UnknownTokens[1].Token = 0x00
10788pp_data->cap[220]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10789pp_data->cap[220]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10790pp_data->cap[220]->pp_cap->UnknownTokens[2].Token = 0x00
10791pp_data->cap[220]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10792pp_data->cap[220]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10793pp_data->cap[220]->pp_cap->UnknownTokens[3].Token = 0x00
10794pp_data->cap[220]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10795pp_data->cap[220]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10796pp_data->cap[220]->NotRange.Usage = 0x0081
10797pp_data->cap[220]->NotRange.Reserved1 = 0x0081
10798pp_data->cap[220]->NotRange.StringIndex = 0
10799pp_data->cap[220]->NotRange.Reserved2 = 0
10800pp_data->cap[220]->NotRange.DesignatorIndex = 0
10801pp_data->cap[220]->NotRange.Reserved3 = 0
10802pp_data->cap[220]->NotRange.DataIndex = 133
10803pp_data->cap[220]->NotRange.Reserved4 = 133
10804pp_data->cap[220]->NotButton.HasNull = 0
10805pp_data->cap[220]->NotButton.Reserved4 = 0x000000
10806pp_data->cap[220]->NotButton.LogicalMin = 0
10807pp_data->cap[220]->NotButton.LogicalMax = 127
10808pp_data->cap[220]->NotButton.PhysicalMin = 0
10809pp_data->cap[220]->NotButton.PhysicalMax = 0
10810pp_data->cap[220]->Units = 0
10811pp_data->cap[220]->UnitsExp = 0
10812
10813# Feature hid_pp_cap struct:
10814pp_data->cap[221]->UsagePage = 0xFF01
10815pp_data->cap[221]->ReportID = 0xD0
10816pp_data->cap[221]->BitPosition = 0
10817pp_data->cap[221]->BitSize = 8
10818pp_data->cap[221]->ReportCount = 32
10819pp_data->cap[221]->BytePosition = 0x0001
10820pp_data->cap[221]->BitCount = 256
10821pp_data->cap[221]->BitField = 0x82
10822pp_data->cap[221]->NextBytePosition = 0x0021
10823pp_data->cap[221]->LinkCollection = 0x0005
10824pp_data->cap[221]->LinkUsagePage = 0xFF01
10825pp_data->cap[221]->LinkUsage = 0x00D0
10826pp_data->cap[221]->IsMultipleItemsForArray = 0
10827pp_data->cap[221]->IsButtonCap = 0
10828pp_data->cap[221]->IsPadding = 0
10829pp_data->cap[221]->IsAbsolute = 1
10830pp_data->cap[221]->IsRange = 0
10831pp_data->cap[221]->IsAlias = 0
10832pp_data->cap[221]->IsStringRange = 0
10833pp_data->cap[221]->IsDesignatorRange = 0
10834pp_data->cap[221]->Reserved1 = 0x000000
10835pp_data->cap[221]->pp_cap->UnknownTokens[0].Token = 0x00
10836pp_data->cap[221]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10837pp_data->cap[221]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10838pp_data->cap[221]->pp_cap->UnknownTokens[1].Token = 0x00
10839pp_data->cap[221]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10840pp_data->cap[221]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10841pp_data->cap[221]->pp_cap->UnknownTokens[2].Token = 0x00
10842pp_data->cap[221]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10843pp_data->cap[221]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10844pp_data->cap[221]->pp_cap->UnknownTokens[3].Token = 0x00
10845pp_data->cap[221]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10846pp_data->cap[221]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10847pp_data->cap[221]->NotRange.Usage = 0x00D1
10848pp_data->cap[221]->NotRange.Reserved1 = 0x00D1
10849pp_data->cap[221]->NotRange.StringIndex = 0
10850pp_data->cap[221]->NotRange.Reserved2 = 0
10851pp_data->cap[221]->NotRange.DesignatorIndex = 0
10852pp_data->cap[221]->NotRange.Reserved3 = 0
10853pp_data->cap[221]->NotRange.DataIndex = 0
10854pp_data->cap[221]->NotRange.Reserved4 = 0
10855pp_data->cap[221]->NotButton.HasNull = 0
10856pp_data->cap[221]->NotButton.Reserved4 = 0x000000
10857pp_data->cap[221]->NotButton.LogicalMin = 0
10858pp_data->cap[221]->NotButton.LogicalMax = 255
10859pp_data->cap[221]->NotButton.PhysicalMin = 0
10860pp_data->cap[221]->NotButton.PhysicalMax = 0
10861pp_data->cap[221]->Units = 0
10862pp_data->cap[221]->UnitsExp = 0
10863
10864pp_data->cap[222]->UsagePage = 0xFF01
10865pp_data->cap[222]->ReportID = 0xD1
10866pp_data->cap[222]->BitPosition = 0
10867pp_data->cap[222]->BitSize = 8
10868pp_data->cap[222]->ReportCount = 32
10869pp_data->cap[222]->BytePosition = 0x0001
10870pp_data->cap[222]->BitCount = 256
10871pp_data->cap[222]->BitField = 0x82
10872pp_data->cap[222]->NextBytePosition = 0x0021
10873pp_data->cap[222]->LinkCollection = 0x0006
10874pp_data->cap[222]->LinkUsagePage = 0xFF01
10875pp_data->cap[222]->LinkUsage = 0x00D0
10876pp_data->cap[222]->IsMultipleItemsForArray = 0
10877pp_data->cap[222]->IsButtonCap = 0
10878pp_data->cap[222]->IsPadding = 0
10879pp_data->cap[222]->IsAbsolute = 1
10880pp_data->cap[222]->IsRange = 0
10881pp_data->cap[222]->IsAlias = 0
10882pp_data->cap[222]->IsStringRange = 0
10883pp_data->cap[222]->IsDesignatorRange = 0
10884pp_data->cap[222]->Reserved1 = 0x000000
10885pp_data->cap[222]->pp_cap->UnknownTokens[0].Token = 0x00
10886pp_data->cap[222]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10887pp_data->cap[222]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10888pp_data->cap[222]->pp_cap->UnknownTokens[1].Token = 0x00
10889pp_data->cap[222]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10890pp_data->cap[222]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10891pp_data->cap[222]->pp_cap->UnknownTokens[2].Token = 0x00
10892pp_data->cap[222]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10893pp_data->cap[222]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10894pp_data->cap[222]->pp_cap->UnknownTokens[3].Token = 0x00
10895pp_data->cap[222]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10896pp_data->cap[222]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10897pp_data->cap[222]->NotRange.Usage = 0x00D1
10898pp_data->cap[222]->NotRange.Reserved1 = 0x00D1
10899pp_data->cap[222]->NotRange.StringIndex = 0
10900pp_data->cap[222]->NotRange.Reserved2 = 0
10901pp_data->cap[222]->NotRange.DesignatorIndex = 0
10902pp_data->cap[222]->NotRange.Reserved3 = 0
10903pp_data->cap[222]->NotRange.DataIndex = 1
10904pp_data->cap[222]->NotRange.Reserved4 = 1
10905pp_data->cap[222]->NotButton.HasNull = 0
10906pp_data->cap[222]->NotButton.Reserved4 = 0x000000
10907pp_data->cap[222]->NotButton.LogicalMin = 0
10908pp_data->cap[222]->NotButton.LogicalMax = 255
10909pp_data->cap[222]->NotButton.PhysicalMin = 0
10910pp_data->cap[222]->NotButton.PhysicalMax = 0
10911pp_data->cap[222]->Units = 0
10912pp_data->cap[222]->UnitsExp = 0
10913
10914pp_data->cap[223]->UsagePage = 0xFF01
10915pp_data->cap[223]->ReportID = 0xD2
10916pp_data->cap[223]->BitPosition = 0
10917pp_data->cap[223]->BitSize = 8
10918pp_data->cap[223]->ReportCount = 32
10919pp_data->cap[223]->BytePosition = 0x0001
10920pp_data->cap[223]->BitCount = 256
10921pp_data->cap[223]->BitField = 0x82
10922pp_data->cap[223]->NextBytePosition = 0x0021
10923pp_data->cap[223]->LinkCollection = 0x0007
10924pp_data->cap[223]->LinkUsagePage = 0xFF01
10925pp_data->cap[223]->LinkUsage = 0x00D0
10926pp_data->cap[223]->IsMultipleItemsForArray = 0
10927pp_data->cap[223]->IsButtonCap = 0
10928pp_data->cap[223]->IsPadding = 0
10929pp_data->cap[223]->IsAbsolute = 1
10930pp_data->cap[223]->IsRange = 0
10931pp_data->cap[223]->IsAlias = 0
10932pp_data->cap[223]->IsStringRange = 0
10933pp_data->cap[223]->IsDesignatorRange = 0
10934pp_data->cap[223]->Reserved1 = 0x000000
10935pp_data->cap[223]->pp_cap->UnknownTokens[0].Token = 0x00
10936pp_data->cap[223]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10937pp_data->cap[223]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10938pp_data->cap[223]->pp_cap->UnknownTokens[1].Token = 0x00
10939pp_data->cap[223]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10940pp_data->cap[223]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10941pp_data->cap[223]->pp_cap->UnknownTokens[2].Token = 0x00
10942pp_data->cap[223]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10943pp_data->cap[223]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10944pp_data->cap[223]->pp_cap->UnknownTokens[3].Token = 0x00
10945pp_data->cap[223]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10946pp_data->cap[223]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10947pp_data->cap[223]->NotRange.Usage = 0x00D1
10948pp_data->cap[223]->NotRange.Reserved1 = 0x00D1
10949pp_data->cap[223]->NotRange.StringIndex = 0
10950pp_data->cap[223]->NotRange.Reserved2 = 0
10951pp_data->cap[223]->NotRange.DesignatorIndex = 0
10952pp_data->cap[223]->NotRange.Reserved3 = 0
10953pp_data->cap[223]->NotRange.DataIndex = 2
10954pp_data->cap[223]->NotRange.Reserved4 = 2
10955pp_data->cap[223]->NotButton.HasNull = 0
10956pp_data->cap[223]->NotButton.Reserved4 = 0x000000
10957pp_data->cap[223]->NotButton.LogicalMin = 0
10958pp_data->cap[223]->NotButton.LogicalMax = 255
10959pp_data->cap[223]->NotButton.PhysicalMin = 0
10960pp_data->cap[223]->NotButton.PhysicalMax = 0
10961pp_data->cap[223]->Units = 0
10962pp_data->cap[223]->UnitsExp = 0
10963
10964pp_data->cap[224]->UsagePage = 0xFF01
10965pp_data->cap[224]->ReportID = 0xD3
10966pp_data->cap[224]->BitPosition = 0
10967pp_data->cap[224]->BitSize = 8
10968pp_data->cap[224]->ReportCount = 32
10969pp_data->cap[224]->BytePosition = 0x0001
10970pp_data->cap[224]->BitCount = 256
10971pp_data->cap[224]->BitField = 0x82
10972pp_data->cap[224]->NextBytePosition = 0x0021
10973pp_data->cap[224]->LinkCollection = 0x0008
10974pp_data->cap[224]->LinkUsagePage = 0xFF01
10975pp_data->cap[224]->LinkUsage = 0x00D0
10976pp_data->cap[224]->IsMultipleItemsForArray = 0
10977pp_data->cap[224]->IsButtonCap = 0
10978pp_data->cap[224]->IsPadding = 0
10979pp_data->cap[224]->IsAbsolute = 1
10980pp_data->cap[224]->IsRange = 0
10981pp_data->cap[224]->IsAlias = 0
10982pp_data->cap[224]->IsStringRange = 0
10983pp_data->cap[224]->IsDesignatorRange = 0
10984pp_data->cap[224]->Reserved1 = 0x000000
10985pp_data->cap[224]->pp_cap->UnknownTokens[0].Token = 0x00
10986pp_data->cap[224]->pp_cap->UnknownTokens[0].Reserved = 0x000000
10987pp_data->cap[224]->pp_cap->UnknownTokens[0].BitField = 0x00000000
10988pp_data->cap[224]->pp_cap->UnknownTokens[1].Token = 0x00
10989pp_data->cap[224]->pp_cap->UnknownTokens[1].Reserved = 0x000000
10990pp_data->cap[224]->pp_cap->UnknownTokens[1].BitField = 0x00000000
10991pp_data->cap[224]->pp_cap->UnknownTokens[2].Token = 0x00
10992pp_data->cap[224]->pp_cap->UnknownTokens[2].Reserved = 0x000000
10993pp_data->cap[224]->pp_cap->UnknownTokens[2].BitField = 0x00000000
10994pp_data->cap[224]->pp_cap->UnknownTokens[3].Token = 0x00
10995pp_data->cap[224]->pp_cap->UnknownTokens[3].Reserved = 0x000000
10996pp_data->cap[224]->pp_cap->UnknownTokens[3].BitField = 0x00000000
10997pp_data->cap[224]->NotRange.Usage = 0x00D1
10998pp_data->cap[224]->NotRange.Reserved1 = 0x00D1
10999pp_data->cap[224]->NotRange.StringIndex = 0
11000pp_data->cap[224]->NotRange.Reserved2 = 0
11001pp_data->cap[224]->NotRange.DesignatorIndex = 0
11002pp_data->cap[224]->NotRange.Reserved3 = 0
11003pp_data->cap[224]->NotRange.DataIndex = 3
11004pp_data->cap[224]->NotRange.Reserved4 = 3
11005pp_data->cap[224]->NotButton.HasNull = 0
11006pp_data->cap[224]->NotButton.Reserved4 = 0x000000
11007pp_data->cap[224]->NotButton.LogicalMin = 0
11008pp_data->cap[224]->NotButton.LogicalMax = 255
11009pp_data->cap[224]->NotButton.PhysicalMin = 0
11010pp_data->cap[224]->NotButton.PhysicalMax = 0
11011pp_data->cap[224]->Units = 0
11012pp_data->cap[224]->UnitsExp = 0
11013
11014pp_data->cap[225]->UsagePage = 0xFF01
11015pp_data->cap[225]->ReportID = 0xD4
11016pp_data->cap[225]->BitPosition = 0
11017pp_data->cap[225]->BitSize = 8
11018pp_data->cap[225]->ReportCount = 32
11019pp_data->cap[225]->BytePosition = 0x0001
11020pp_data->cap[225]->BitCount = 256
11021pp_data->cap[225]->BitField = 0x82
11022pp_data->cap[225]->NextBytePosition = 0x0021
11023pp_data->cap[225]->LinkCollection = 0x0009
11024pp_data->cap[225]->LinkUsagePage = 0xFF01
11025pp_data->cap[225]->LinkUsage = 0x00D0
11026pp_data->cap[225]->IsMultipleItemsForArray = 0
11027pp_data->cap[225]->IsButtonCap = 0
11028pp_data->cap[225]->IsPadding = 0
11029pp_data->cap[225]->IsAbsolute = 1
11030pp_data->cap[225]->IsRange = 0
11031pp_data->cap[225]->IsAlias = 0
11032pp_data->cap[225]->IsStringRange = 0
11033pp_data->cap[225]->IsDesignatorRange = 0
11034pp_data->cap[225]->Reserved1 = 0x000000
11035pp_data->cap[225]->pp_cap->UnknownTokens[0].Token = 0x00
11036pp_data->cap[225]->pp_cap->UnknownTokens[0].Reserved = 0x000000
11037pp_data->cap[225]->pp_cap->UnknownTokens[0].BitField = 0x00000000
11038pp_data->cap[225]->pp_cap->UnknownTokens[1].Token = 0x00
11039pp_data->cap[225]->pp_cap->UnknownTokens[1].Reserved = 0x000000
11040pp_data->cap[225]->pp_cap->UnknownTokens[1].BitField = 0x00000000
11041pp_data->cap[225]->pp_cap->UnknownTokens[2].Token = 0x00
11042pp_data->cap[225]->pp_cap->UnknownTokens[2].Reserved = 0x000000
11043pp_data->cap[225]->pp_cap->UnknownTokens[2].BitField = 0x00000000
11044pp_data->cap[225]->pp_cap->UnknownTokens[3].Token = 0x00
11045pp_data->cap[225]->pp_cap->UnknownTokens[3].Reserved = 0x000000
11046pp_data->cap[225]->pp_cap->UnknownTokens[3].BitField = 0x00000000
11047pp_data->cap[225]->NotRange.Usage = 0x00D1
11048pp_data->cap[225]->NotRange.Reserved1 = 0x00D1
11049pp_data->cap[225]->NotRange.StringIndex = 0
11050pp_data->cap[225]->NotRange.Reserved2 = 0
11051pp_data->cap[225]->NotRange.DesignatorIndex = 0
11052pp_data->cap[225]->NotRange.Reserved3 = 0
11053pp_data->cap[225]->NotRange.DataIndex = 4
11054pp_data->cap[225]->NotRange.Reserved4 = 4
11055pp_data->cap[225]->NotButton.HasNull = 0
11056pp_data->cap[225]->NotButton.Reserved4 = 0x000000
11057pp_data->cap[225]->NotButton.LogicalMin = 0
11058pp_data->cap[225]->NotButton.LogicalMax = 255
11059pp_data->cap[225]->NotButton.PhysicalMin = 0
11060pp_data->cap[225]->NotButton.PhysicalMax = 0
11061pp_data->cap[225]->Units = 0
11062pp_data->cap[225]->UnitsExp = 0
11063
11064pp_data->cap[226]->UsagePage = 0xFF01
11065pp_data->cap[226]->ReportID = 0xD5
11066pp_data->cap[226]->BitPosition = 0
11067pp_data->cap[226]->BitSize = 8
11068pp_data->cap[226]->ReportCount = 32
11069pp_data->cap[226]->BytePosition = 0x0001
11070pp_data->cap[226]->BitCount = 256
11071pp_data->cap[226]->BitField = 0x82
11072pp_data->cap[226]->NextBytePosition = 0x0021
11073pp_data->cap[226]->LinkCollection = 0x000A
11074pp_data->cap[226]->LinkUsagePage = 0xFF01
11075pp_data->cap[226]->LinkUsage = 0x00D0
11076pp_data->cap[226]->IsMultipleItemsForArray = 0
11077pp_data->cap[226]->IsButtonCap = 0
11078pp_data->cap[226]->IsPadding = 0
11079pp_data->cap[226]->IsAbsolute = 1
11080pp_data->cap[226]->IsRange = 0
11081pp_data->cap[226]->IsAlias = 0
11082pp_data->cap[226]->IsStringRange = 0
11083pp_data->cap[226]->IsDesignatorRange = 0
11084pp_data->cap[226]->Reserved1 = 0x000000
11085pp_data->cap[226]->pp_cap->UnknownTokens[0].Token = 0x00
11086pp_data->cap[226]->pp_cap->UnknownTokens[0].Reserved = 0x000000
11087pp_data->cap[226]->pp_cap->UnknownTokens[0].BitField = 0x00000000
11088pp_data->cap[226]->pp_cap->UnknownTokens[1].Token = 0x00
11089pp_data->cap[226]->pp_cap->UnknownTokens[1].Reserved = 0x000000
11090pp_data->cap[226]->pp_cap->UnknownTokens[1].BitField = 0x00000000
11091pp_data->cap[226]->pp_cap->UnknownTokens[2].Token = 0x00
11092pp_data->cap[226]->pp_cap->UnknownTokens[2].Reserved = 0x000000
11093pp_data->cap[226]->pp_cap->UnknownTokens[2].BitField = 0x00000000
11094pp_data->cap[226]->pp_cap->UnknownTokens[3].Token = 0x00
11095pp_data->cap[226]->pp_cap->UnknownTokens[3].Reserved = 0x000000
11096pp_data->cap[226]->pp_cap->UnknownTokens[3].BitField = 0x00000000
11097pp_data->cap[226]->NotRange.Usage = 0x00D1
11098pp_data->cap[226]->NotRange.Reserved1 = 0x00D1
11099pp_data->cap[226]->NotRange.StringIndex = 0
11100pp_data->cap[226]->NotRange.Reserved2 = 0
11101pp_data->cap[226]->NotRange.DesignatorIndex = 0
11102pp_data->cap[226]->NotRange.Reserved3 = 0
11103pp_data->cap[226]->NotRange.DataIndex = 5
11104pp_data->cap[226]->NotRange.Reserved4 = 5
11105pp_data->cap[226]->NotButton.HasNull = 0
11106pp_data->cap[226]->NotButton.Reserved4 = 0x000000
11107pp_data->cap[226]->NotButton.LogicalMin = 0
11108pp_data->cap[226]->NotButton.LogicalMax = 255
11109pp_data->cap[226]->NotButton.PhysicalMin = 0
11110pp_data->cap[226]->NotButton.PhysicalMax = 0
11111pp_data->cap[226]->Units = 0
11112pp_data->cap[226]->UnitsExp = 0
11113
11114pp_data->cap[227]->UsagePage = 0xFF01
11115pp_data->cap[227]->ReportID = 0xD6
11116pp_data->cap[227]->BitPosition = 0
11117pp_data->cap[227]->BitSize = 8
11118pp_data->cap[227]->ReportCount = 32
11119pp_data->cap[227]->BytePosition = 0x0001
11120pp_data->cap[227]->BitCount = 256
11121pp_data->cap[227]->BitField = 0x82
11122pp_data->cap[227]->NextBytePosition = 0x0021
11123pp_data->cap[227]->LinkCollection = 0x000B
11124pp_data->cap[227]->LinkUsagePage = 0xFF01
11125pp_data->cap[227]->LinkUsage = 0x00D0
11126pp_data->cap[227]->IsMultipleItemsForArray = 0
11127pp_data->cap[227]->IsButtonCap = 0
11128pp_data->cap[227]->IsPadding = 0
11129pp_data->cap[227]->IsAbsolute = 1
11130pp_data->cap[227]->IsRange = 0
11131pp_data->cap[227]->IsAlias = 0
11132pp_data->cap[227]->IsStringRange = 0
11133pp_data->cap[227]->IsDesignatorRange = 0
11134pp_data->cap[227]->Reserved1 = 0x000000
11135pp_data->cap[227]->pp_cap->UnknownTokens[0].Token = 0x00
11136pp_data->cap[227]->pp_cap->UnknownTokens[0].Reserved = 0x000000
11137pp_data->cap[227]->pp_cap->UnknownTokens[0].BitField = 0x00000000
11138pp_data->cap[227]->pp_cap->UnknownTokens[1].Token = 0x00
11139pp_data->cap[227]->pp_cap->UnknownTokens[1].Reserved = 0x000000
11140pp_data->cap[227]->pp_cap->UnknownTokens[1].BitField = 0x00000000
11141pp_data->cap[227]->pp_cap->UnknownTokens[2].Token = 0x00
11142pp_data->cap[227]->pp_cap->UnknownTokens[2].Reserved = 0x000000
11143pp_data->cap[227]->pp_cap->UnknownTokens[2].BitField = 0x00000000
11144pp_data->cap[227]->pp_cap->UnknownTokens[3].Token = 0x00
11145pp_data->cap[227]->pp_cap->UnknownTokens[3].Reserved = 0x000000
11146pp_data->cap[227]->pp_cap->UnknownTokens[3].BitField = 0x00000000
11147pp_data->cap[227]->NotRange.Usage = 0x00D1
11148pp_data->cap[227]->NotRange.Reserved1 = 0x00D1
11149pp_data->cap[227]->NotRange.StringIndex = 0
11150pp_data->cap[227]->NotRange.Reserved2 = 0
11151pp_data->cap[227]->NotRange.DesignatorIndex = 0
11152pp_data->cap[227]->NotRange.Reserved3 = 0
11153pp_data->cap[227]->NotRange.DataIndex = 6
11154pp_data->cap[227]->NotRange.Reserved4 = 6
11155pp_data->cap[227]->NotButton.HasNull = 0
11156pp_data->cap[227]->NotButton.Reserved4 = 0x000000
11157pp_data->cap[227]->NotButton.LogicalMin = 0
11158pp_data->cap[227]->NotButton.LogicalMax = 255
11159pp_data->cap[227]->NotButton.PhysicalMin = 0
11160pp_data->cap[227]->NotButton.PhysicalMax = 0
11161pp_data->cap[227]->Units = 0
11162pp_data->cap[227]->UnitsExp = 0
11163
11164pp_data->cap[228]->UsagePage = 0xFF01
11165pp_data->cap[228]->ReportID = 0xD8
11166pp_data->cap[228]->BitPosition = 0
11167pp_data->cap[228]->BitSize = 8
11168pp_data->cap[228]->ReportCount = 32
11169pp_data->cap[228]->BytePosition = 0x0001
11170pp_data->cap[228]->BitCount = 256
11171pp_data->cap[228]->BitField = 0x82
11172pp_data->cap[228]->NextBytePosition = 0x0021
11173pp_data->cap[228]->LinkCollection = 0x000C
11174pp_data->cap[228]->LinkUsagePage = 0xFF01
11175pp_data->cap[228]->LinkUsage = 0x00D0
11176pp_data->cap[228]->IsMultipleItemsForArray = 0
11177pp_data->cap[228]->IsButtonCap = 0
11178pp_data->cap[228]->IsPadding = 0
11179pp_data->cap[228]->IsAbsolute = 1
11180pp_data->cap[228]->IsRange = 0
11181pp_data->cap[228]->IsAlias = 0
11182pp_data->cap[228]->IsStringRange = 0
11183pp_data->cap[228]->IsDesignatorRange = 0
11184pp_data->cap[228]->Reserved1 = 0x000000
11185pp_data->cap[228]->pp_cap->UnknownTokens[0].Token = 0x00
11186pp_data->cap[228]->pp_cap->UnknownTokens[0].Reserved = 0x000000
11187pp_data->cap[228]->pp_cap->UnknownTokens[0].BitField = 0x00000000
11188pp_data->cap[228]->pp_cap->UnknownTokens[1].Token = 0x00
11189pp_data->cap[228]->pp_cap->UnknownTokens[1].Reserved = 0x000000
11190pp_data->cap[228]->pp_cap->UnknownTokens[1].BitField = 0x00000000
11191pp_data->cap[228]->pp_cap->UnknownTokens[2].Token = 0x00
11192pp_data->cap[228]->pp_cap->UnknownTokens[2].Reserved = 0x000000
11193pp_data->cap[228]->pp_cap->UnknownTokens[2].BitField = 0x00000000
11194pp_data->cap[228]->pp_cap->UnknownTokens[3].Token = 0x00
11195pp_data->cap[228]->pp_cap->UnknownTokens[3].Reserved = 0x000000
11196pp_data->cap[228]->pp_cap->UnknownTokens[3].BitField = 0x00000000
11197pp_data->cap[228]->NotRange.Usage = 0x00D1
11198pp_data->cap[228]->NotRange.Reserved1 = 0x00D1
11199pp_data->cap[228]->NotRange.StringIndex = 0
11200pp_data->cap[228]->NotRange.Reserved2 = 0
11201pp_data->cap[228]->NotRange.DesignatorIndex = 0
11202pp_data->cap[228]->NotRange.Reserved3 = 0
11203pp_data->cap[228]->NotRange.DataIndex = 7
11204pp_data->cap[228]->NotRange.Reserved4 = 7
11205pp_data->cap[228]->NotButton.HasNull = 0
11206pp_data->cap[228]->NotButton.Reserved4 = 0x000000
11207pp_data->cap[228]->NotButton.LogicalMin = 0
11208pp_data->cap[228]->NotButton.LogicalMax = 255
11209pp_data->cap[228]->NotButton.PhysicalMin = 0
11210pp_data->cap[228]->NotButton.PhysicalMax = 0
11211pp_data->cap[228]->Units = 0
11212pp_data->cap[228]->UnitsExp = 0
11213
11214pp_data->cap[229]->UsagePage = 0xFF01
11215pp_data->cap[229]->ReportID = 0xD9
11216pp_data->cap[229]->BitPosition = 0
11217pp_data->cap[229]->BitSize = 8
11218pp_data->cap[229]->ReportCount = 32
11219pp_data->cap[229]->BytePosition = 0x0001
11220pp_data->cap[229]->BitCount = 256
11221pp_data->cap[229]->BitField = 0x82
11222pp_data->cap[229]->NextBytePosition = 0x0021
11223pp_data->cap[229]->LinkCollection = 0x000D
11224pp_data->cap[229]->LinkUsagePage = 0xFF01
11225pp_data->cap[229]->LinkUsage = 0x00D0
11226pp_data->cap[229]->IsMultipleItemsForArray = 0
11227pp_data->cap[229]->IsButtonCap = 0
11228pp_data->cap[229]->IsPadding = 0
11229pp_data->cap[229]->IsAbsolute = 1
11230pp_data->cap[229]->IsRange = 0
11231pp_data->cap[229]->IsAlias = 0
11232pp_data->cap[229]->IsStringRange = 0
11233pp_data->cap[229]->IsDesignatorRange = 0
11234pp_data->cap[229]->Reserved1 = 0x000000
11235pp_data->cap[229]->pp_cap->UnknownTokens[0].Token = 0x00
11236pp_data->cap[229]->pp_cap->UnknownTokens[0].Reserved = 0x000000
11237pp_data->cap[229]->pp_cap->UnknownTokens[0].BitField = 0x00000000
11238pp_data->cap[229]->pp_cap->UnknownTokens[1].Token = 0x00
11239pp_data->cap[229]->pp_cap->UnknownTokens[1].Reserved = 0x000000
11240pp_data->cap[229]->pp_cap->UnknownTokens[1].BitField = 0x00000000
11241pp_data->cap[229]->pp_cap->UnknownTokens[2].Token = 0x00
11242pp_data->cap[229]->pp_cap->UnknownTokens[2].Reserved = 0x000000
11243pp_data->cap[229]->pp_cap->UnknownTokens[2].BitField = 0x00000000
11244pp_data->cap[229]->pp_cap->UnknownTokens[3].Token = 0x00
11245pp_data->cap[229]->pp_cap->UnknownTokens[3].Reserved = 0x000000
11246pp_data->cap[229]->pp_cap->UnknownTokens[3].BitField = 0x00000000
11247pp_data->cap[229]->NotRange.Usage = 0x00D1
11248pp_data->cap[229]->NotRange.Reserved1 = 0x00D1
11249pp_data->cap[229]->NotRange.StringIndex = 0
11250pp_data->cap[229]->NotRange.Reserved2 = 0
11251pp_data->cap[229]->NotRange.DesignatorIndex = 0
11252pp_data->cap[229]->NotRange.Reserved3 = 0
11253pp_data->cap[229]->NotRange.DataIndex = 8
11254pp_data->cap[229]->NotRange.Reserved4 = 8
11255pp_data->cap[229]->NotButton.HasNull = 0
11256pp_data->cap[229]->NotButton.Reserved4 = 0x000000
11257pp_data->cap[229]->NotButton.LogicalMin = 0
11258pp_data->cap[229]->NotButton.LogicalMax = 255
11259pp_data->cap[229]->NotButton.PhysicalMin = 0
11260pp_data->cap[229]->NotButton.PhysicalMax = 0
11261pp_data->cap[229]->Units = 0
11262pp_data->cap[229]->UnitsExp = 0
11263
11264pp_data->cap[230]->UsagePage = 0xFF01
11265pp_data->cap[230]->ReportID = 0xF1
11266pp_data->cap[230]->BitPosition = 0
11267pp_data->cap[230]->BitSize = 8
11268pp_data->cap[230]->ReportCount = 2
11269pp_data->cap[230]->BytePosition = 0x0001
11270pp_data->cap[230]->BitCount = 16
11271pp_data->cap[230]->BitField = 0x82
11272pp_data->cap[230]->NextBytePosition = 0x0003
11273pp_data->cap[230]->LinkCollection = 0x000E
11274pp_data->cap[230]->LinkUsagePage = 0xFF01
11275pp_data->cap[230]->LinkUsage = 0x00D0
11276pp_data->cap[230]->IsMultipleItemsForArray = 0
11277pp_data->cap[230]->IsButtonCap = 0
11278pp_data->cap[230]->IsPadding = 0
11279pp_data->cap[230]->IsAbsolute = 1
11280pp_data->cap[230]->IsRange = 0
11281pp_data->cap[230]->IsAlias = 0
11282pp_data->cap[230]->IsStringRange = 0
11283pp_data->cap[230]->IsDesignatorRange = 0
11284pp_data->cap[230]->Reserved1 = 0x000000
11285pp_data->cap[230]->pp_cap->UnknownTokens[0].Token = 0x00
11286pp_data->cap[230]->pp_cap->UnknownTokens[0].Reserved = 0x000000
11287pp_data->cap[230]->pp_cap->UnknownTokens[0].BitField = 0x00000000
11288pp_data->cap[230]->pp_cap->UnknownTokens[1].Token = 0x00
11289pp_data->cap[230]->pp_cap->UnknownTokens[1].Reserved = 0x000000
11290pp_data->cap[230]->pp_cap->UnknownTokens[1].BitField = 0x00000000
11291pp_data->cap[230]->pp_cap->UnknownTokens[2].Token = 0x00
11292pp_data->cap[230]->pp_cap->UnknownTokens[2].Reserved = 0x000000
11293pp_data->cap[230]->pp_cap->UnknownTokens[2].BitField = 0x00000000
11294pp_data->cap[230]->pp_cap->UnknownTokens[3].Token = 0x00
11295pp_data->cap[230]->pp_cap->UnknownTokens[3].Reserved = 0x000000
11296pp_data->cap[230]->pp_cap->UnknownTokens[3].BitField = 0x00000000
11297pp_data->cap[230]->NotRange.Usage = 0x00D1
11298pp_data->cap[230]->NotRange.Reserved1 = 0x00D1
11299pp_data->cap[230]->NotRange.StringIndex = 0
11300pp_data->cap[230]->NotRange.Reserved2 = 0
11301pp_data->cap[230]->NotRange.DesignatorIndex = 0
11302pp_data->cap[230]->NotRange.Reserved3 = 0
11303pp_data->cap[230]->NotRange.DataIndex = 9
11304pp_data->cap[230]->NotRange.Reserved4 = 9
11305pp_data->cap[230]->NotButton.HasNull = 0
11306pp_data->cap[230]->NotButton.Reserved4 = 0x000000
11307pp_data->cap[230]->NotButton.LogicalMin = 0
11308pp_data->cap[230]->NotButton.LogicalMax = 255
11309pp_data->cap[230]->NotButton.PhysicalMin = 0
11310pp_data->cap[230]->NotButton.PhysicalMax = 0
11311pp_data->cap[230]->Units = 0
11312pp_data->cap[230]->UnitsExp = 0
11313
11314pp_data->cap[231]->UsagePage = 0xFF01
11315pp_data->cap[231]->ReportID = 0xF3
11316pp_data->cap[231]->BitPosition = 0
11317pp_data->cap[231]->BitSize = 8
11318pp_data->cap[231]->ReportCount = 2
11319pp_data->cap[231]->BytePosition = 0x0001
11320pp_data->cap[231]->BitCount = 16
11321pp_data->cap[231]->BitField = 0x82
11322pp_data->cap[231]->NextBytePosition = 0x0003
11323pp_data->cap[231]->LinkCollection = 0x000F
11324pp_data->cap[231]->LinkUsagePage = 0xFF01
11325pp_data->cap[231]->LinkUsage = 0x00D0
11326pp_data->cap[231]->IsMultipleItemsForArray = 0
11327pp_data->cap[231]->IsButtonCap = 0
11328pp_data->cap[231]->IsPadding = 0
11329pp_data->cap[231]->IsAbsolute = 1
11330pp_data->cap[231]->IsRange = 0
11331pp_data->cap[231]->IsAlias = 0
11332pp_data->cap[231]->IsStringRange = 0
11333pp_data->cap[231]->IsDesignatorRange = 0
11334pp_data->cap[231]->Reserved1 = 0x000000
11335pp_data->cap[231]->pp_cap->UnknownTokens[0].Token = 0x00
11336pp_data->cap[231]->pp_cap->UnknownTokens[0].Reserved = 0x000000
11337pp_data->cap[231]->pp_cap->UnknownTokens[0].BitField = 0x00000000
11338pp_data->cap[231]->pp_cap->UnknownTokens[1].Token = 0x00
11339pp_data->cap[231]->pp_cap->UnknownTokens[1].Reserved = 0x000000
11340pp_data->cap[231]->pp_cap->UnknownTokens[1].BitField = 0x00000000
11341pp_data->cap[231]->pp_cap->UnknownTokens[2].Token = 0x00
11342pp_data->cap[231]->pp_cap->UnknownTokens[2].Reserved = 0x000000
11343pp_data->cap[231]->pp_cap->UnknownTokens[2].BitField = 0x00000000
11344pp_data->cap[231]->pp_cap->UnknownTokens[3].Token = 0x00
11345pp_data->cap[231]->pp_cap->UnknownTokens[3].Reserved = 0x000000
11346pp_data->cap[231]->pp_cap->UnknownTokens[3].BitField = 0x00000000
11347pp_data->cap[231]->NotRange.Usage = 0x00D1
11348pp_data->cap[231]->NotRange.Reserved1 = 0x00D1
11349pp_data->cap[231]->NotRange.StringIndex = 0
11350pp_data->cap[231]->NotRange.Reserved2 = 0
11351pp_data->cap[231]->NotRange.DesignatorIndex = 0
11352pp_data->cap[231]->NotRange.Reserved3 = 0
11353pp_data->cap[231]->NotRange.DataIndex = 10
11354pp_data->cap[231]->NotRange.Reserved4 = 10
11355pp_data->cap[231]->NotButton.HasNull = 0
11356pp_data->cap[231]->NotButton.Reserved4 = 0x000000
11357pp_data->cap[231]->NotButton.LogicalMin = 0
11358pp_data->cap[231]->NotButton.LogicalMax = 127
11359pp_data->cap[231]->NotButton.PhysicalMin = 0
11360pp_data->cap[231]->NotButton.PhysicalMax = 0
11361pp_data->cap[231]->Units = 0
11362pp_data->cap[231]->UnitsExp = 0
11363
11364# Link Collections:
11365pp_data->LinkCollectionArray[0]->LinkUsage = 0x0000
11366pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF01
11367pp_data->LinkCollectionArray[0]->Parent = 0
11368pp_data->LinkCollectionArray[0]->NumberOfChildren = 15
11369pp_data->LinkCollectionArray[0]->NextSibling = 0
11370pp_data->LinkCollectionArray[0]->FirstChild = 15
11371pp_data->LinkCollectionArray[0]->CollectionType = 1
11372pp_data->LinkCollectionArray[0]->IsAlias = 0
11373pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
11374pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
11375pp_data->LinkCollectionArray[1]->LinkUsagePage = 0xFF01
11376pp_data->LinkCollectionArray[1]->Parent = 0
11377pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
11378pp_data->LinkCollectionArray[1]->NextSibling = 0
11379pp_data->LinkCollectionArray[1]->FirstChild = 0
11380pp_data->LinkCollectionArray[1]->CollectionType = 2
11381pp_data->LinkCollectionArray[1]->IsAlias = 0
11382pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
11383pp_data->LinkCollectionArray[2]->LinkUsage = 0x0002
11384pp_data->LinkCollectionArray[2]->LinkUsagePage = 0xFF01
11385pp_data->LinkCollectionArray[2]->Parent = 0
11386pp_data->LinkCollectionArray[2]->NumberOfChildren = 0
11387pp_data->LinkCollectionArray[2]->NextSibling = 1
11388pp_data->LinkCollectionArray[2]->FirstChild = 0
11389pp_data->LinkCollectionArray[2]->CollectionType = 2
11390pp_data->LinkCollectionArray[2]->IsAlias = 0
11391pp_data->LinkCollectionArray[2]->Reserved = 0x00000000
11392pp_data->LinkCollectionArray[3]->LinkUsage = 0x0080
11393pp_data->LinkCollectionArray[3]->LinkUsagePage = 0xFF01
11394pp_data->LinkCollectionArray[3]->Parent = 0
11395pp_data->LinkCollectionArray[3]->NumberOfChildren = 0
11396pp_data->LinkCollectionArray[3]->NextSibling = 2
11397pp_data->LinkCollectionArray[3]->FirstChild = 0
11398pp_data->LinkCollectionArray[3]->CollectionType = 2
11399pp_data->LinkCollectionArray[3]->IsAlias = 0
11400pp_data->LinkCollectionArray[3]->Reserved = 0x00000000
11401pp_data->LinkCollectionArray[4]->LinkUsage = 0x0080
11402pp_data->LinkCollectionArray[4]->LinkUsagePage = 0xFF01
11403pp_data->LinkCollectionArray[4]->Parent = 0
11404pp_data->LinkCollectionArray[4]->NumberOfChildren = 0
11405pp_data->LinkCollectionArray[4]->NextSibling = 3
11406pp_data->LinkCollectionArray[4]->FirstChild = 0
11407pp_data->LinkCollectionArray[4]->CollectionType = 2
11408pp_data->LinkCollectionArray[4]->IsAlias = 0
11409pp_data->LinkCollectionArray[4]->Reserved = 0x00000000
11410pp_data->LinkCollectionArray[5]->LinkUsage = 0x00D0
11411pp_data->LinkCollectionArray[5]->LinkUsagePage = 0xFF01
11412pp_data->LinkCollectionArray[5]->Parent = 0
11413pp_data->LinkCollectionArray[5]->NumberOfChildren = 0
11414pp_data->LinkCollectionArray[5]->NextSibling = 4
11415pp_data->LinkCollectionArray[5]->FirstChild = 0
11416pp_data->LinkCollectionArray[5]->CollectionType = 2
11417pp_data->LinkCollectionArray[5]->IsAlias = 0
11418pp_data->LinkCollectionArray[5]->Reserved = 0x00000000
11419pp_data->LinkCollectionArray[6]->LinkUsage = 0x00D0
11420pp_data->LinkCollectionArray[6]->LinkUsagePage = 0xFF01
11421pp_data->LinkCollectionArray[6]->Parent = 0
11422pp_data->LinkCollectionArray[6]->NumberOfChildren = 0
11423pp_data->LinkCollectionArray[6]->NextSibling = 5
11424pp_data->LinkCollectionArray[6]->FirstChild = 0
11425pp_data->LinkCollectionArray[6]->CollectionType = 2
11426pp_data->LinkCollectionArray[6]->IsAlias = 0
11427pp_data->LinkCollectionArray[6]->Reserved = 0x00000000
11428pp_data->LinkCollectionArray[7]->LinkUsage = 0x00D0
11429pp_data->LinkCollectionArray[7]->LinkUsagePage = 0xFF01
11430pp_data->LinkCollectionArray[7]->Parent = 0
11431pp_data->LinkCollectionArray[7]->NumberOfChildren = 0
11432pp_data->LinkCollectionArray[7]->NextSibling = 6
11433pp_data->LinkCollectionArray[7]->FirstChild = 0
11434pp_data->LinkCollectionArray[7]->CollectionType = 2
11435pp_data->LinkCollectionArray[7]->IsAlias = 0
11436pp_data->LinkCollectionArray[7]->Reserved = 0x00000000
11437pp_data->LinkCollectionArray[8]->LinkUsage = 0x00D0
11438pp_data->LinkCollectionArray[8]->LinkUsagePage = 0xFF01
11439pp_data->LinkCollectionArray[8]->Parent = 0
11440pp_data->LinkCollectionArray[8]->NumberOfChildren = 0
11441pp_data->LinkCollectionArray[8]->NextSibling = 7
11442pp_data->LinkCollectionArray[8]->FirstChild = 0
11443pp_data->LinkCollectionArray[8]->CollectionType = 2
11444pp_data->LinkCollectionArray[8]->IsAlias = 0
11445pp_data->LinkCollectionArray[8]->Reserved = 0x00000000
11446pp_data->LinkCollectionArray[9]->LinkUsage = 0x00D0
11447pp_data->LinkCollectionArray[9]->LinkUsagePage = 0xFF01
11448pp_data->LinkCollectionArray[9]->Parent = 0
11449pp_data->LinkCollectionArray[9]->NumberOfChildren = 0
11450pp_data->LinkCollectionArray[9]->NextSibling = 8
11451pp_data->LinkCollectionArray[9]->FirstChild = 0
11452pp_data->LinkCollectionArray[9]->CollectionType = 2
11453pp_data->LinkCollectionArray[9]->IsAlias = 0
11454pp_data->LinkCollectionArray[9]->Reserved = 0x00000000
11455pp_data->LinkCollectionArray[10]->LinkUsage = 0x00D0
11456pp_data->LinkCollectionArray[10]->LinkUsagePage = 0xFF01
11457pp_data->LinkCollectionArray[10]->Parent = 0
11458pp_data->LinkCollectionArray[10]->NumberOfChildren = 0
11459pp_data->LinkCollectionArray[10]->NextSibling = 9
11460pp_data->LinkCollectionArray[10]->FirstChild = 0
11461pp_data->LinkCollectionArray[10]->CollectionType = 2
11462pp_data->LinkCollectionArray[10]->IsAlias = 0
11463pp_data->LinkCollectionArray[10]->Reserved = 0x00000000
11464pp_data->LinkCollectionArray[11]->LinkUsage = 0x00D0
11465pp_data->LinkCollectionArray[11]->LinkUsagePage = 0xFF01
11466pp_data->LinkCollectionArray[11]->Parent = 0
11467pp_data->LinkCollectionArray[11]->NumberOfChildren = 0
11468pp_data->LinkCollectionArray[11]->NextSibling = 10
11469pp_data->LinkCollectionArray[11]->FirstChild = 0
11470pp_data->LinkCollectionArray[11]->CollectionType = 2
11471pp_data->LinkCollectionArray[11]->IsAlias = 0
11472pp_data->LinkCollectionArray[11]->Reserved = 0x00000000
11473pp_data->LinkCollectionArray[12]->LinkUsage = 0x00D0
11474pp_data->LinkCollectionArray[12]->LinkUsagePage = 0xFF01
11475pp_data->LinkCollectionArray[12]->Parent = 0
11476pp_data->LinkCollectionArray[12]->NumberOfChildren = 0
11477pp_data->LinkCollectionArray[12]->NextSibling = 11
11478pp_data->LinkCollectionArray[12]->FirstChild = 0
11479pp_data->LinkCollectionArray[12]->CollectionType = 2
11480pp_data->LinkCollectionArray[12]->IsAlias = 0
11481pp_data->LinkCollectionArray[12]->Reserved = 0x00000000
11482pp_data->LinkCollectionArray[13]->LinkUsage = 0x00D0
11483pp_data->LinkCollectionArray[13]->LinkUsagePage = 0xFF01
11484pp_data->LinkCollectionArray[13]->Parent = 0
11485pp_data->LinkCollectionArray[13]->NumberOfChildren = 0
11486pp_data->LinkCollectionArray[13]->NextSibling = 12
11487pp_data->LinkCollectionArray[13]->FirstChild = 0
11488pp_data->LinkCollectionArray[13]->CollectionType = 2
11489pp_data->LinkCollectionArray[13]->IsAlias = 0
11490pp_data->LinkCollectionArray[13]->Reserved = 0x00000000
11491pp_data->LinkCollectionArray[14]->LinkUsage = 0x00D0
11492pp_data->LinkCollectionArray[14]->LinkUsagePage = 0xFF01
11493pp_data->LinkCollectionArray[14]->Parent = 0
11494pp_data->LinkCollectionArray[14]->NumberOfChildren = 0
11495pp_data->LinkCollectionArray[14]->NextSibling = 13
11496pp_data->LinkCollectionArray[14]->FirstChild = 0
11497pp_data->LinkCollectionArray[14]->CollectionType = 2
11498pp_data->LinkCollectionArray[14]->IsAlias = 0
11499pp_data->LinkCollectionArray[14]->Reserved = 0x00000000
11500pp_data->LinkCollectionArray[15]->LinkUsage = 0x00D0
11501pp_data->LinkCollectionArray[15]->LinkUsagePage = 0xFF01
11502pp_data->LinkCollectionArray[15]->Parent = 0
11503pp_data->LinkCollectionArray[15]->NumberOfChildren = 0
11504pp_data->LinkCollectionArray[15]->NextSibling = 14
11505pp_data->LinkCollectionArray[15]->FirstChild = 0
11506pp_data->LinkCollectionArray[15]->CollectionType = 2
11507pp_data->LinkCollectionArray[15]->IsAlias = 0
11508pp_data->LinkCollectionArray[15]->Reserved = 0x00000000
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_expected.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_expected.rpt_desc
new file mode 100644
index 0000000..9bcc814
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_expected.rpt_desc
@@ -0,0 +1,75 @@
10x06, 0x01, 0xFF, 0x09, 0x00, 0xA1, 0x01, 0x09, 0x01, 0xA1,
20x02, 0x85, 0x01, 0x09, 0x03, 0x09, 0x03, 0x09, 0x03, 0x09,
30x03, 0x15, 0x00, 0x25, 0x0F, 0x75, 0x04, 0x95, 0x04, 0x81,
40x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
50x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
60x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
70x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
80x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
90x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
100x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
110x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
120x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
130x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x0B, 0x09,
140x0B, 0x09, 0x0B, 0x09, 0x0B, 0x09, 0x0B, 0x09, 0x0B, 0x09,
150x0B, 0x09, 0x0B, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95,
160x38, 0x81, 0x02, 0xC0, 0x09, 0x02, 0xA1, 0x02, 0x85, 0x02,
170x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
180x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
190x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
200x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
210x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
220x09, 0x04, 0x15, 0x00, 0x26, 0xFF, 0x0F, 0x75, 0x10, 0x95,
230x1A, 0x81, 0x02, 0xC0, 0x09, 0x80, 0xA1, 0x02, 0x85, 0x80,
240x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
250x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
260x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
270x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
280x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
290x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
300x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
310x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
320x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
330x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
340x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
350x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
360x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
370x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
380x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
390x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
400x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
410x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
420x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x15, 0x00,
430x25, 0x7F, 0x75, 0x08, 0x95, 0x5E, 0x91, 0x02, 0xC0, 0x09,
440x80, 0xA1, 0x02, 0x85, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
450x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
460x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
470x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
480x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
490x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
500x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
510x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
520x81, 0x09, 0x81, 0x09, 0x81, 0x15, 0x00, 0x25, 0x7F, 0x75,
530x08, 0x95, 0x28, 0x91, 0x02, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
540x85, 0xD0, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
550x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
560x85, 0xD1, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
570x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
580x85, 0xD2, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
590x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
600x85, 0xD3, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
610x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
620x85, 0xD4, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
630x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
640x85, 0xD5, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
650x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
660x85, 0xD6, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
670x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
680x85, 0xD8, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
690x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
700x85, 0xD9, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
710x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
720x85, 0xF1, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
730x08, 0x95, 0x02, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
740x85, 0xF3, 0x09, 0xD1, 0x15, 0x00, 0x25, 0x7F, 0x75, 0x08,
750x95, 0x02, 0xB1, 0x82, 0xC0, 0xC0, \ No newline at end of file
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_real.rpt_desc b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_real.rpt_desc
new file mode 100644
index 0000000..7f908f8
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/data/17CC_1130_0000_FF01_real.rpt_desc
@@ -0,0 +1,381 @@
1Usage Page (Vendor-Defined 2) 06 01 FF
2Usage (Undefined) 09 00
3Collection (Application) A1 01
4 Usage (Vendor-Defined 1) 09 01
5 Collection (Logical) A1 02
6 Report ID (1) 85 01
7 Usage (Vendor-Defined 3) 09 03
8 Usage (Vendor-Defined 3) 09 03
9 Usage (Vendor-Defined 3) 09 03
10 Usage (Vendor-Defined 3) 09 03
11 Logical Minimum (0) 15 00
12 Logical Maximum (15) 25 0F
13 Report Size (4) 75 04
14 Report Count (4) 95 04
15 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
16 Usage (Vendor-Defined 2) 09 02
17 Usage (Vendor-Defined 2) 09 02
18 Usage (Vendor-Defined 2) 09 02
19 Usage (Vendor-Defined 2) 09 02
20 Usage (Vendor-Defined 2) 09 02
21 Usage (Vendor-Defined 2) 09 02
22 Usage (Vendor-Defined 2) 09 02
23 Usage (Vendor-Defined 2) 09 02
24 Usage (Vendor-Defined 2) 09 02
25 Usage (Vendor-Defined 2) 09 02
26 Usage (Vendor-Defined 2) 09 02
27 Usage (Vendor-Defined 2) 09 02
28 Usage (Vendor-Defined 2) 09 02
29 Usage (Vendor-Defined 2) 09 02
30 Usage (Vendor-Defined 2) 09 02
31 Usage (Vendor-Defined 2) 09 02
32 Usage (Vendor-Defined 2) 09 02
33 Usage (Vendor-Defined 2) 09 02
34 Usage (Vendor-Defined 2) 09 02
35 Usage (Vendor-Defined 2) 09 02
36 Usage (Vendor-Defined 2) 09 02
37 Usage (Vendor-Defined 2) 09 02
38 Usage (Vendor-Defined 2) 09 02
39 Usage (Vendor-Defined 2) 09 02
40 Usage (Vendor-Defined 2) 09 02
41 Usage (Vendor-Defined 2) 09 02
42 Usage (Vendor-Defined 2) 09 02
43 Usage (Vendor-Defined 2) 09 02
44 Usage (Vendor-Defined 2) 09 02
45 Usage (Vendor-Defined 2) 09 02
46 Usage (Vendor-Defined 2) 09 02
47 Usage (Vendor-Defined 2) 09 02
48 Usage (Vendor-Defined 2) 09 02
49 Usage (Vendor-Defined 2) 09 02
50 Usage (Vendor-Defined 2) 09 02
51 Usage (Vendor-Defined 2) 09 02
52 Usage (Vendor-Defined 2) 09 02
53 Usage (Vendor-Defined 2) 09 02
54 Usage (Vendor-Defined 2) 09 02
55 Usage (Vendor-Defined 2) 09 02
56 Usage (Vendor-Defined 2) 09 02
57 Usage (Vendor-Defined 2) 09 02
58 Usage (Vendor-Defined 2) 09 02
59 Usage (Vendor-Defined 2) 09 02
60 Usage (Vendor-Defined 2) 09 02
61 Usage (Vendor-Defined 2) 09 02
62 Usage (Vendor-Defined 2) 09 02
63 Usage (Vendor-Defined 2) 09 02
64 Logical Minimum (0) 15 00
65 Logical Maximum (1) 25 01
66 Report Size (1) 75 01
67 Report Count (48) 95 30
68 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
69 Usage (Vendor-Defined 11) 09 0B
70 Usage (Vendor-Defined 11) 09 0B
71 Usage (Vendor-Defined 11) 09 0B
72 Usage (Vendor-Defined 11) 09 0B
73 Usage (Vendor-Defined 11) 09 0B
74 Usage (Vendor-Defined 11) 09 0B
75 Usage (Vendor-Defined 11) 09 0B
76 Usage (Vendor-Defined 11) 09 0B
77 Logical Minimum (0) 15 00
78 Logical Maximum (1) 25 01
79 Report Size (1) 75 01
80 Report Count (8) 95 08
81 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
82 End Collection C0
83 Usage (Vendor-Defined 2) 09 02
84 Collection (Logical) A1 02
85 Report ID (2) 85 02
86 Usage (Vendor-Defined 4) 09 04
87 Usage (Vendor-Defined 4) 09 04
88 Usage (Vendor-Defined 4) 09 04
89 Usage (Vendor-Defined 4) 09 04
90 Usage (Vendor-Defined 4) 09 04
91 Usage (Vendor-Defined 4) 09 04
92 Usage (Vendor-Defined 4) 09 04
93 Usage (Vendor-Defined 4) 09 04
94 Usage (Vendor-Defined 4) 09 04
95 Usage (Vendor-Defined 4) 09 04
96 Usage (Vendor-Defined 4) 09 04
97 Usage (Vendor-Defined 4) 09 04
98 Usage (Vendor-Defined 4) 09 04
99 Usage (Vendor-Defined 4) 09 04
100 Usage (Vendor-Defined 4) 09 04
101 Usage (Vendor-Defined 4) 09 04
102 Usage (Vendor-Defined 4) 09 04
103 Usage (Vendor-Defined 4) 09 04
104 Usage (Vendor-Defined 4) 09 04
105 Usage (Vendor-Defined 4) 09 04
106 Usage (Vendor-Defined 4) 09 04
107 Usage (Vendor-Defined 4) 09 04
108 Usage (Vendor-Defined 4) 09 04
109 Usage (Vendor-Defined 4) 09 04
110 Usage (Vendor-Defined 4) 09 04
111 Usage (Vendor-Defined 4) 09 04
112 Usage (Vendor-Defined 4) 09 04
113 Logical Minimum (0) 15 00
114 Logical Maximum (4095) 26 FF 0F
115 Report Size (16) 75 10
116 Report Count (26) 95 1A
117 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
118 End Collection C0
119 Usage (Vendor-Defined 128) 09 80
120 Collection (Logical) A1 02
121 Report ID (128) 85 80
122 Usage (Vendor-Defined 129) 09 81
123 Usage (Vendor-Defined 129) 09 81
124 Usage (Vendor-Defined 129) 09 81
125 Usage (Vendor-Defined 129) 09 81
126 Usage (Vendor-Defined 129) 09 81
127 Usage (Vendor-Defined 129) 09 81
128 Usage (Vendor-Defined 129) 09 81
129 Usage (Vendor-Defined 129) 09 81
130 Usage (Vendor-Defined 129) 09 81
131 Usage (Vendor-Defined 129) 09 81
132 Usage (Vendor-Defined 129) 09 81
133 Usage (Vendor-Defined 129) 09 81
134 Usage (Vendor-Defined 129) 09 81
135 Usage (Vendor-Defined 129) 09 81
136 Usage (Vendor-Defined 129) 09 81
137 Usage (Vendor-Defined 129) 09 81
138 Usage (Vendor-Defined 129) 09 81
139 Usage (Vendor-Defined 129) 09 81
140 Usage (Vendor-Defined 129) 09 81
141 Usage (Vendor-Defined 129) 09 81
142 Usage (Vendor-Defined 129) 09 81
143 Usage (Vendor-Defined 129) 09 81
144 Usage (Vendor-Defined 129) 09 81
145 Usage (Vendor-Defined 129) 09 81
146 Usage (Vendor-Defined 129) 09 81
147 Usage (Vendor-Defined 129) 09 81
148 Usage (Vendor-Defined 129) 09 81
149 Usage (Vendor-Defined 129) 09 81
150 Usage (Vendor-Defined 129) 09 81
151 Usage (Vendor-Defined 129) 09 81
152 Usage (Vendor-Defined 129) 09 81
153 Usage (Vendor-Defined 129) 09 81
154 Usage (Vendor-Defined 129) 09 81
155 Usage (Vendor-Defined 129) 09 81
156 Usage (Vendor-Defined 129) 09 81
157 Usage (Vendor-Defined 129) 09 81
158 Usage (Vendor-Defined 129) 09 81
159 Usage (Vendor-Defined 129) 09 81
160 Usage (Vendor-Defined 129) 09 81
161 Usage (Vendor-Defined 129) 09 81
162 Usage (Vendor-Defined 129) 09 81
163 Usage (Vendor-Defined 129) 09 81
164 Usage (Vendor-Defined 129) 09 81
165 Usage (Vendor-Defined 129) 09 81
166 Usage (Vendor-Defined 129) 09 81
167 Usage (Vendor-Defined 129) 09 81
168 Usage (Vendor-Defined 129) 09 81
169 Usage (Vendor-Defined 129) 09 81
170 Usage (Vendor-Defined 129) 09 81
171 Usage (Vendor-Defined 129) 09 81
172 Usage (Vendor-Defined 129) 09 81
173 Usage (Vendor-Defined 129) 09 81
174 Usage (Vendor-Defined 129) 09 81
175 Usage (Vendor-Defined 129) 09 81
176 Usage (Vendor-Defined 129) 09 81
177 Usage (Vendor-Defined 129) 09 81
178 Usage (Vendor-Defined 129) 09 81
179 Usage (Vendor-Defined 129) 09 81
180 Usage (Vendor-Defined 129) 09 81
181 Usage (Vendor-Defined 129) 09 81
182 Usage (Vendor-Defined 129) 09 81
183 Usage (Vendor-Defined 129) 09 81
184 Usage (Vendor-Defined 129) 09 81
185 Usage (Vendor-Defined 129) 09 81
186 Usage (Vendor-Defined 129) 09 81
187 Usage (Vendor-Defined 129) 09 81
188 Usage (Vendor-Defined 129) 09 81
189 Usage (Vendor-Defined 129) 09 81
190 Usage (Vendor-Defined 129) 09 81
191 Usage (Vendor-Defined 129) 09 81
192 Usage (Vendor-Defined 129) 09 81
193 Usage (Vendor-Defined 129) 09 81
194 Usage (Vendor-Defined 129) 09 81
195 Usage (Vendor-Defined 129) 09 81
196 Usage (Vendor-Defined 129) 09 81
197 Usage (Vendor-Defined 129) 09 81
198 Usage (Vendor-Defined 129) 09 81
199 Usage (Vendor-Defined 129) 09 81
200 Usage (Vendor-Defined 129) 09 81
201 Usage (Vendor-Defined 129) 09 81
202 Usage (Vendor-Defined 129) 09 81
203 Usage (Vendor-Defined 129) 09 81
204 Usage (Vendor-Defined 129) 09 81
205 Usage (Vendor-Defined 129) 09 81
206 Usage (Vendor-Defined 129) 09 81
207 Usage (Vendor-Defined 129) 09 81
208 Usage (Vendor-Defined 129) 09 81
209 Usage (Vendor-Defined 129) 09 81
210 Usage (Vendor-Defined 129) 09 81
211 Usage (Vendor-Defined 129) 09 81
212 Usage (Vendor-Defined 129) 09 81
213 Usage (Vendor-Defined 129) 09 81
214 Usage (Vendor-Defined 129) 09 81
215 Usage (Vendor-Defined 129) 09 81
216 Logical Minimum (0) 15 00
217 Logical Maximum (127) 25 7F
218 Report Count (94) 95 5E
219 Report Size (8) 75 08
220 Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
221 End Collection C0
222 Usage (Vendor-Defined 128) 09 80
223 Collection (Logical) A1 02
224 Report ID (129) 85 81
225 Usage (Vendor-Defined 129) 09 81
226 Usage (Vendor-Defined 129) 09 81
227 Usage (Vendor-Defined 129) 09 81
228 Usage (Vendor-Defined 129) 09 81
229 Usage (Vendor-Defined 129) 09 81
230 Usage (Vendor-Defined 129) 09 81
231 Usage (Vendor-Defined 129) 09 81
232 Usage (Vendor-Defined 129) 09 81
233 Usage (Vendor-Defined 129) 09 81
234 Usage (Vendor-Defined 129) 09 81
235 Usage (Vendor-Defined 129) 09 81
236 Usage (Vendor-Defined 129) 09 81
237 Usage (Vendor-Defined 129) 09 81
238 Usage (Vendor-Defined 129) 09 81
239 Usage (Vendor-Defined 129) 09 81
240 Usage (Vendor-Defined 129) 09 81
241 Usage (Vendor-Defined 129) 09 81
242 Usage (Vendor-Defined 129) 09 81
243 Usage (Vendor-Defined 129) 09 81
244 Usage (Vendor-Defined 129) 09 81
245 Usage (Vendor-Defined 129) 09 81
246 Usage (Vendor-Defined 129) 09 81
247 Usage (Vendor-Defined 129) 09 81
248 Usage (Vendor-Defined 129) 09 81
249 Usage (Vendor-Defined 129) 09 81
250 Usage (Vendor-Defined 129) 09 81
251 Usage (Vendor-Defined 129) 09 81
252 Usage (Vendor-Defined 129) 09 81
253 Usage (Vendor-Defined 129) 09 81
254 Usage (Vendor-Defined 129) 09 81
255 Usage (Vendor-Defined 129) 09 81
256 Usage (Vendor-Defined 129) 09 81
257 Usage (Vendor-Defined 129) 09 81
258 Usage (Vendor-Defined 129) 09 81
259 Usage (Vendor-Defined 129) 09 81
260 Usage (Vendor-Defined 129) 09 81
261 Usage (Vendor-Defined 129) 09 81
262 Usage (Vendor-Defined 129) 09 81
263 Usage (Vendor-Defined 129) 09 81
264 Usage (Vendor-Defined 129) 09 81
265 Logical Minimum (0) 15 00
266 Logical Maximum (127) 25 7F
267 Report Count (40) 95 28
268 Report Size (8) 75 08
269 Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
270 End Collection C0
271 Usage (Vendor-Defined 208) 09 D0
272 Collection (Logical) A1 02
273 Report ID (208) 85 D0
274 Usage (Vendor-Defined 209) 09 D1
275 Logical Minimum (0) 15 00
276 Logical Maximum (255) 26 FF 00
277 Report Size (8) 75 08
278 Report Count (32) 95 20
279 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
280 End Collection C0
281 Usage (Vendor-Defined 208) 09 D0
282 Collection (Logical) A1 02
283 Report ID (209) 85 D1
284 Usage (Vendor-Defined 209) 09 D1
285 Logical Minimum (0) 15 00
286 Logical Maximum (255) 26 FF 00
287 Report Size (8) 75 08
288 Report Count (32) 95 20
289 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
290 End Collection C0
291 Usage (Vendor-Defined 208) 09 D0
292 Collection (Logical) A1 02
293 Report ID (210) 85 D2
294 Usage (Vendor-Defined 209) 09 D1
295 Logical Minimum (0) 15 00
296 Logical Maximum (255) 26 FF 00
297 Report Size (8) 75 08
298 Report Count (32) 95 20
299 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
300 End Collection C0
301 Usage (Vendor-Defined 208) 09 D0
302 Collection (Logical) A1 02
303 Report ID (211) 85 D3
304 Usage (Vendor-Defined 209) 09 D1
305 Logical Minimum (0) 15 00
306 Logical Maximum (255) 26 FF 00
307 Report Size (8) 75 08
308 Report Count (32) 95 20
309 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
310 End Collection C0
311 Usage (Vendor-Defined 208) 09 D0
312 Collection (Logical) A1 02
313 Report ID (212) 85 D4
314 Usage (Vendor-Defined 209) 09 D1
315 Logical Minimum (0) 15 00
316 Logical Maximum (255) 26 FF 00
317 Report Size (8) 75 08
318 Report Count (32) 95 20
319 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
320 End Collection C0
321 Usage (Vendor-Defined 208) 09 D0
322 Collection (Logical) A1 02
323 Report ID (213) 85 D5
324 Usage (Vendor-Defined 209) 09 D1
325 Logical Minimum (0) 15 00
326 Logical Maximum (255) 26 FF 00
327 Report Size (8) 75 08
328 Report Count (32) 95 20
329 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
330 End Collection C0
331 Usage (Vendor-Defined 208) 09 D0
332 Collection (Logical) A1 02
333 Report ID (214) 85 D6
334 Usage (Vendor-Defined 209) 09 D1
335 Logical Minimum (0) 15 00
336 Logical Maximum (255) 26 FF 00
337 Report Size (8) 75 08
338 Report Count (32) 95 20
339 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
340 End Collection C0
341 Usage (Vendor-Defined 208) 09 D0
342 Collection (Logical) A1 02
343 Report ID (216) 85 D8
344 Usage (Vendor-Defined 209) 09 D1
345 Logical Minimum (0) 15 00
346 Logical Maximum (255) 26 FF 00
347 Report Size (8) 75 08
348 Report Count (32) 95 20
349 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
350 End Collection C0
351 Usage (Vendor-Defined 208) 09 D0
352 Collection (Logical) A1 02
353 Report ID (217) 85 D9
354 Usage (Vendor-Defined 209) 09 D1
355 Logical Minimum (0) 15 00
356 Logical Maximum (255) 26 FF 00
357 Report Size (8) 75 08
358 Report Count (32) 95 20
359 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
360 End Collection C0
361 Usage (Vendor-Defined 208) 09 D0
362 Collection (Logical) A1 02
363 Report ID (241) 85 F1
364 Usage (Vendor-Defined 209) 09 D1
365 Logical Minimum (0) 15 00
366 Logical Maximum (255) 26 FF 00
367 Report Size (8) 75 08
368 Report Count (2) 95 02
369 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
370 End Collection C0
371 Usage (Vendor-Defined 208) 09 D0
372 Collection (Logical) A1 02
373 Report ID (243) 85 F3
374 Usage (Vendor-Defined 209) 09 D1
375 Logical Minimum (0) 15 00
376 Logical Maximum (127) 25 7F
377 Report Size (8) 75 08
378 Report Count (2) 95 02
379 Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
380 End Collection C0
381End Collection C0
diff --git a/contrib/SDL-3.2.8/src/hidapi/windows/test/hid_report_reconstructor_test.c b/contrib/SDL-3.2.8/src/hidapi/windows/test/hid_report_reconstructor_test.c
new file mode 100644
index 0000000..a7adeb5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/windows/test/hid_report_reconstructor_test.c
@@ -0,0 +1,563 @@
1#if defined(__MINGW32__)
2 // Needed for %zu
3 #define __USE_MINGW_ANSI_STDIO 1
4#endif
5
6#include "../hidapi_descriptor_reconstruct.h"
7
8#include <stddef.h>
9#include <stdio.h>
10#include <string.h>
11
12static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
13{
14 FILE* file;
15 errno_t err = fopen_s(&file, filename, "r");
16
17 if (err != 0) {
18 fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, strerror(err));
19 return NULL;
20 }
21
22 char line[256];
23
24 {
25 unsigned short vendor_id = 0;
26 unsigned short product_id = 0;
27 unsigned short usage = 0;
28 unsigned short usage_page = 0;
29 unsigned short release_number = 0;
30 int interface_number = -1;
31 BOOLEAN header_read_success = FALSE;
32 char manufacturer_string[128];
33 manufacturer_string[0] = '\0';
34 char product_string[128];
35 product_string[0] = '\0';
36 // char path[128];
37 // path[0] = '\0';
38
39 while (fgets(line, sizeof(line), file) != NULL) {
40 if (line[0] == '\r' || line[0] == '\n') {
41 line[0] = '\0';
42 }
43 if (line[0] == '\0') {
44 // read the 'metadata' only until the first empty line
45 header_read_success = TRUE;
46 break;
47 }
48 if (sscanf(line, "dev->vendor_id = 0x%04hX\n", &vendor_id)) continue;
49 if (sscanf(line, "dev->product_id = 0x%04hX\n", &product_id)) continue;
50 if (sscanf(line, "dev->usage_page = 0x%04hX\n", &usage_page)) continue;
51 if (sscanf(line, "dev->usage = 0x%04hX\n", &usage)) continue;
52 if (sscanf(line, "dev->manufacturer_string = \"%127[^\"\n]", manufacturer_string)) continue;
53 if (sscanf(line, "dev->product_string = \"%127[^\"\n]", product_string)) continue;
54 if (sscanf(line, "dev->release_number = 0x%04hX\n", &release_number)) continue;
55 if (sscanf(line, "dev->interface_number = %d\n", &interface_number)) continue;
56 // if (sscanf(line, "dev->path = \"%127[^\"]\n", path)) continue;
57 }
58 if (!header_read_success) {
59 fprintf(stderr, "ERROR: Couldn't read PP Data header (missing newline)\n");
60 fclose(file);
61 return NULL;
62 }
63 printf("'Virtual' Device Read: %04hx %04hx\n", vendor_id, product_id);
64 if (manufacturer_string[0] != '\0') {
65 printf(" Manufacturer: %s\n", manufacturer_string);
66 }
67 if (product_string[0] != '\0') {
68 printf(" Product: %s\n", product_string);
69 }
70 printf(" Release: %hx\n", release_number);
71 printf(" Interface: %d\n", interface_number);
72 printf(" Usage (page): 0x%hx (0x%hx)\n", usage, usage_page);
73 }
74
75 hidp_preparsed_data static_pp_data;
76 memset(&static_pp_data, 0, sizeof(static_pp_data));
77 hidp_preparsed_data *pp_data = &static_pp_data;
78
79 unsigned int rt_idx;
80 unsigned int caps_idx;
81 unsigned int token_idx;
82 unsigned int coll_idx;
83 USAGE temp_usage;
84 BOOLEAN temp_boolean[3];
85 UCHAR temp_uchar[3];
86 USHORT temp_ushort;
87 ULONG temp_ulong;
88 LONG temp_long;
89
90 USHORT FirstByteOfLinkCollectionArray = 0;
91 USHORT NumberLinkCollectionNodes = 0;
92
93 while (fgets(line, sizeof(line), file) != NULL) {
94 if (line[0] == '#')
95 continue;
96
97 if (FirstByteOfLinkCollectionArray != 0 && NumberLinkCollectionNodes != 0) {
98 size_t size_of_preparsed_data = offsetof(hidp_preparsed_data, caps) + FirstByteOfLinkCollectionArray + (NumberLinkCollectionNodes * sizeof(hid_pp_link_collection_node));
99 pp_data->FirstByteOfLinkCollectionArray = FirstByteOfLinkCollectionArray;
100 pp_data->NumberLinkCollectionNodes = NumberLinkCollectionNodes;
101 FirstByteOfLinkCollectionArray = 0;
102 NumberLinkCollectionNodes = 0;
103 pp_data = malloc(size_of_preparsed_data);
104 memcpy(pp_data, &static_pp_data, sizeof(static_pp_data));
105 }
106
107 if (sscanf(line, "pp_data->MagicKey = 0x%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX\n", &pp_data->MagicKey[0], &pp_data->MagicKey[1], &pp_data->MagicKey[2], &pp_data->MagicKey[3], &pp_data->MagicKey[4], &pp_data->MagicKey[5], &pp_data->MagicKey[6], &pp_data->MagicKey[7])) continue;
108 if (sscanf(line, "pp_data->Usage = 0x%04hX\n", &pp_data->Usage)) continue;
109 if (sscanf(line, "pp_data->UsagePage = 0x%04hX\n", &pp_data->UsagePage)) continue;
110 if (sscanf(line, "pp_data->Reserved = 0x%04hX%04hX\n", &pp_data->Reserved[0], &pp_data->Reserved[1])) continue;
111
112 if (sscanf(line, "pp_data->caps_info[%u]", &rt_idx) == 1) {
113 const size_t caps_info_count = sizeof(pp_data->caps_info) / sizeof(pp_data->caps_info[0]);
114 if (rt_idx >= caps_info_count) {
115 fprintf(stderr, "Broken pp_data file, pp_data->caps_info[<idx>] can have at most %zu elements, accessing %ud, (%s)", caps_info_count, rt_idx, line);
116 continue;
117 }
118 if (sscanf(line, "pp_data->caps_info[%u]->FirstCap = %hu\n", &rt_idx, &temp_ushort) == 2) {
119 pp_data->caps_info[rt_idx].FirstCap = temp_ushort;
120 continue;
121 }
122 if (sscanf(line, "pp_data->caps_info[%u]->LastCap = %hu\n", &rt_idx, &temp_ushort) == 2) {
123 pp_data->caps_info[rt_idx].LastCap = temp_ushort;
124 continue;
125 }
126 if (sscanf(line, "pp_data->caps_info[%u]->NumberOfCaps = %hu\n", &rt_idx, &temp_ushort) == 2) {
127 pp_data->caps_info[rt_idx].NumberOfCaps = temp_ushort;
128 continue;
129 }
130 if (sscanf(line, "pp_data->caps_info[%u]->ReportByteLength = %hu\n", &rt_idx, &temp_ushort) == 2) {
131 pp_data->caps_info[rt_idx].ReportByteLength = temp_ushort;
132 continue;
133 }
134 fprintf(stderr, "Ignoring unimplemented caps_info field: %s", line);
135 continue;
136 }
137
138 if (sscanf(line, "pp_data->FirstByteOfLinkCollectionArray = 0x%04hX\n", &FirstByteOfLinkCollectionArray)) {
139 continue;
140 }
141 if (sscanf(line, "pp_data->NumberLinkCollectionNodes = %hu\n", &NumberLinkCollectionNodes)) {
142 continue;
143 }
144
145 if (sscanf(line, "pp_data->cap[%u]", &caps_idx) == 1) {
146 if (pp_data->FirstByteOfLinkCollectionArray == 0) {
147 fprintf(stderr, "Error reading pp_data file (%s): FirstByteOfLinkCollectionArray is 0 or not reported yet\n", line);
148 continue;
149 }
150 if ((caps_idx + 1) * sizeof(hid_pp_cap) > pp_data->FirstByteOfLinkCollectionArray) {
151 fprintf(stderr, "Error reading pp_data file (%s): the caps index (%u) is out of pp_data bytes boundary (%hu vs %hu)\n", line, caps_idx, (unsigned short) ((caps_idx + 1) * sizeof(hid_pp_cap)), pp_data->FirstByteOfLinkCollectionArray);
152 continue;
153 }
154 if (sscanf(line, "pp_data->cap[%u]->UsagePage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
155 pp_data->caps[caps_idx].UsagePage = temp_usage;
156 continue;
157 }
158 if (sscanf(line, "pp_data->cap[%u]->ReportID = 0x%02hhX\n", &caps_idx, &temp_uchar[0]) == 2) {
159 pp_data->caps[caps_idx].ReportID = temp_uchar[0];
160 continue;
161 }
162 if (sscanf(line, "pp_data->cap[%u]->BitPosition = %hhu\n", &caps_idx, &temp_uchar[0]) == 2) {
163 pp_data->caps[caps_idx].BitPosition = temp_uchar[0];
164 continue;
165 }
166 if (sscanf(line, "pp_data->cap[%u]->BitSize = %hu\n", &caps_idx, &temp_ushort) == 2) {
167 pp_data->caps[caps_idx].ReportSize = temp_ushort;
168 continue;
169 }
170 if (sscanf(line, "pp_data->cap[%u]->ReportCount = %hu\n", &caps_idx, &temp_ushort) == 2) {
171 pp_data->caps[caps_idx].ReportCount = temp_ushort;
172 continue;
173 }
174 if (sscanf(line, "pp_data->cap[%u]->BytePosition = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
175 pp_data->caps[caps_idx].BytePosition = temp_ushort;
176 continue;
177 }
178 if (sscanf(line, "pp_data->cap[%u]->BitCount = %hu\n", &caps_idx, &temp_ushort) == 2) {
179 pp_data->caps[caps_idx].BitCount = temp_ushort;
180 continue;
181 }
182 if (sscanf(line, "pp_data->cap[%u]->BitField = 0x%02lX\n", &caps_idx, &temp_ulong) == 2) {
183 pp_data->caps[caps_idx].BitField = temp_ulong;
184 continue;
185 }
186 if (sscanf(line, "pp_data->cap[%u]->NextBytePosition = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
187 pp_data->caps[caps_idx].NextBytePosition = temp_ushort;
188 continue;
189 }
190 if (sscanf(line, "pp_data->cap[%u]->LinkCollection = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
191 pp_data->caps[caps_idx].LinkCollection = temp_ushort;
192 continue;
193 }
194 if (sscanf(line, "pp_data->cap[%u]->LinkUsagePage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
195 pp_data->caps[caps_idx].LinkUsagePage = temp_usage;
196 continue;
197 }
198 if (sscanf(line, "pp_data->cap[%u]->LinkUsage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
199 pp_data->caps[caps_idx].LinkUsage = temp_usage;
200 continue;
201 }
202
203 // 8 Flags in one byte
204 if (sscanf(line, "pp_data->cap[%u]->IsMultipleItemsForArray = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
205 pp_data->caps[caps_idx].IsMultipleItemsForArray = temp_boolean[0];
206 continue;
207 }
208 if (sscanf(line, "pp_data->cap[%u]->IsButtonCap = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
209 pp_data->caps[caps_idx].IsButtonCap = temp_boolean[0];
210 continue;
211 }
212 if (sscanf(line, "pp_data->cap[%u]->IsPadding = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
213 pp_data->caps[caps_idx].IsPadding = temp_boolean[0];
214 continue;
215 }
216 if (sscanf(line, "pp_data->cap[%u]->IsAbsolute = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
217 pp_data->caps[caps_idx].IsAbsolute = temp_boolean[0];
218 continue;
219 }
220 if (sscanf(line, "pp_data->cap[%u]->IsRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
221 pp_data->caps[caps_idx].IsRange = temp_boolean[0];
222 continue;
223 }
224 if (sscanf(line, "pp_data->cap[%u]->IsAlias = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
225 pp_data->caps[caps_idx].IsAlias = temp_boolean[0];
226 continue;
227 }
228 if (sscanf(line, "pp_data->cap[%u]->IsStringRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
229 pp_data->caps[caps_idx].IsStringRange = temp_boolean[0];
230 continue;
231 }
232 if (sscanf(line, "pp_data->cap[%u]->IsDesignatorRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
233 pp_data->caps[caps_idx].IsDesignatorRange = temp_boolean[0];
234 continue;
235 }
236
237 if (sscanf(line, "pp_data->cap[%u]->Reserved1 = 0x%hhu%hhu%hhu\n", &caps_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
238 pp_data->caps[caps_idx].Reserved1[0] = temp_uchar[0];
239 pp_data->caps[caps_idx].Reserved1[1] = temp_uchar[1];
240 pp_data->caps[caps_idx].Reserved1[2] = temp_uchar[2];
241 continue;
242 }
243
244 if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u]", &caps_idx, &token_idx) == 2) {
245 const size_t unknown_tokens_count = sizeof(pp_data->caps[0].UnknownTokens) / sizeof(pp_data->caps[0].UnknownTokens[0]);
246 if (token_idx >= unknown_tokens_count) {
247 fprintf(stderr, "Broken pp_data file, pp_data->caps[<idx>].UnknownTokens[<idx>] can have at most %zu elements, accessing %ud, (%s)", unknown_tokens_count, token_idx, line);
248 continue;
249 }
250 if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u].Token = 0x%02hhX\n", &caps_idx, &token_idx, &temp_uchar[0]) == 3) {
251 pp_data->caps[caps_idx].UnknownTokens[token_idx].Token = temp_uchar[0];
252 continue;
253 }
254 if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u].Reserved = 0x%02hhX%02hhX%02hhX\n", &caps_idx, &token_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 5) {
255 pp_data->caps[caps_idx].UnknownTokens[token_idx].Reserved[0] = temp_uchar[0];
256 pp_data->caps[caps_idx].UnknownTokens[token_idx].Reserved[1] = temp_uchar[1];
257 pp_data->caps[caps_idx].UnknownTokens[token_idx].Reserved[2] = temp_uchar[2];
258 continue;
259 }
260 if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u].BitField = 0x%08lX\n", &caps_idx, &token_idx, &temp_ulong) == 3) {
261 pp_data->caps[caps_idx].UnknownTokens[token_idx].BitField = temp_ulong;
262 continue;
263 }
264 fprintf(stderr, "Ignoring unimplemented pp_data->cap[]->pp_cap->UnknownTokens field: %s", line);
265 continue;
266 }
267
268 // Range
269 if (sscanf(line, "pp_data->cap[%u]->Range.UsageMin = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
270 pp_data->caps[caps_idx].Range.UsageMin = temp_usage;
271 continue;
272 }
273 if (sscanf(line, "pp_data->cap[%u]->Range.UsageMax = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
274 pp_data->caps[caps_idx].Range.UsageMax = temp_usage;
275 continue;
276 }
277 if (sscanf(line, "pp_data->cap[%u]->Range.StringMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
278 pp_data->caps[caps_idx].Range.StringMin = temp_ushort;
279 continue;
280 }
281 if (sscanf(line, "pp_data->cap[%u]->Range.StringMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
282 pp_data->caps[caps_idx].Range.StringMax = temp_ushort;
283 continue;
284 }
285 if (sscanf(line, "pp_data->cap[%u]->Range.DesignatorMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
286 pp_data->caps[caps_idx].Range.DesignatorMin = temp_ushort;
287 continue;
288 }
289 if (sscanf(line, "pp_data->cap[%u]->Range.DesignatorMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
290 pp_data->caps[caps_idx].Range.DesignatorMax = temp_ushort;
291 continue;
292 }
293 if (sscanf(line, "pp_data->cap[%u]->Range.DataIndexMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
294 pp_data->caps[caps_idx].Range.DataIndexMin = temp_ushort;
295 continue;
296 }
297 if (sscanf(line, "pp_data->cap[%u]->Range.DataIndexMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
298 pp_data->caps[caps_idx].Range.DataIndexMax = temp_ushort;
299 continue;
300 }
301
302 // NotRange
303 if (sscanf(line, "pp_data->cap[%u]->NotRange.Usage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
304 pp_data->caps[caps_idx].NotRange.Usage = temp_usage;
305 continue;
306 }
307 if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved1 = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
308 pp_data->caps[caps_idx].NotRange.Reserved1 = temp_usage;
309 continue;
310 }
311 if (sscanf(line, "pp_data->cap[%u]->NotRange.StringIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
312 pp_data->caps[caps_idx].NotRange.StringIndex = temp_ushort;
313 continue;
314 }
315 if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved2 = %hu\n", &caps_idx, &temp_ushort) == 2) {
316 pp_data->caps[caps_idx].NotRange.Reserved2 = temp_ushort;
317 continue;
318 }
319 if (sscanf(line, "pp_data->cap[%u]->NotRange.DesignatorIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
320 pp_data->caps[caps_idx].NotRange.DesignatorIndex = temp_ushort;
321 continue;
322 }
323 if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved3 = %hu\n", &caps_idx, &temp_ushort) == 2) {
324 pp_data->caps[caps_idx].NotRange.Reserved3 = temp_ushort;
325 continue;
326 }
327 if (sscanf(line, "pp_data->cap[%u]->NotRange.DataIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
328 pp_data->caps[caps_idx].NotRange.DataIndex = temp_ushort;
329 continue;
330 }
331 if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved4 = %hu\n", &caps_idx, &temp_ushort) == 2) {
332 pp_data->caps[caps_idx].NotRange.Reserved4 = temp_ushort;
333 continue;
334 }
335
336 // Button
337 if (sscanf(line, "pp_data->cap[%u]->Button.LogicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
338 pp_data->caps[caps_idx].Button.LogicalMin = temp_long;
339 continue;
340 }
341 if (sscanf(line, "pp_data->cap[%u]->Button.LogicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
342 pp_data->caps[caps_idx].Button.LogicalMax = temp_long;
343 continue;
344 }
345
346 // NotButton
347 if (sscanf(line, "pp_data->cap[%u]->NotButton.HasNull = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
348 pp_data->caps[caps_idx].NotButton.HasNull = temp_boolean[0];
349 continue;
350 }
351 if (sscanf(line, "pp_data->cap[%u]->NotButton.Reserved4 = 0x%02hhX%02hhX%02hhX\n", &caps_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
352 pp_data->caps[caps_idx].NotButton.Reserved4[0] = temp_uchar[0];
353 pp_data->caps[caps_idx].NotButton.Reserved4[1] = temp_uchar[1];
354 pp_data->caps[caps_idx].NotButton.Reserved4[2] = temp_uchar[2];
355 continue;
356 }
357 if (sscanf(line, "pp_data->cap[%u]->NotButton.LogicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
358 pp_data->caps[caps_idx].NotButton.LogicalMin = temp_long;
359 continue;
360 }
361 if (sscanf(line, "pp_data->cap[%u]->NotButton.LogicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
362 pp_data->caps[caps_idx].NotButton.LogicalMax = temp_long;
363 continue;
364 }
365 if (sscanf(line, "pp_data->cap[%u]->NotButton.PhysicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
366 pp_data->caps[caps_idx].NotButton.PhysicalMin = temp_long;
367 continue;
368 }
369 if (sscanf(line, "pp_data->cap[%u]->NotButton.PhysicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
370 pp_data->caps[caps_idx].NotButton.PhysicalMax = temp_long;
371 continue;
372 }
373
374 if (sscanf(line, "pp_data->cap[%u]->Units = %lu\n", &caps_idx, &temp_ulong) == 2) {
375 pp_data->caps[caps_idx].Units = temp_ulong;
376 continue;
377 }
378 if (sscanf(line, "pp_data->cap[%u]->UnitsExp = %lu\n", &caps_idx, &temp_ulong) == 2) {
379 pp_data->caps[caps_idx].UnitsExp = temp_ulong;
380 continue;
381 }
382 if (sscanf(line, "pp_data->cap[%u]->Reserved1 = 0x%02hhu%02hhu%02hhu\n", &coll_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
383 pp_data->caps[caps_idx].Reserved1[0] = temp_uchar[0];
384 pp_data->caps[caps_idx].Reserved1[1] = temp_uchar[1];
385 pp_data->caps[caps_idx].Reserved1[2] = temp_uchar[2];
386 continue;
387 }
388 fprintf(stderr, "Ignoring unimplemented cap field: %s", line);
389 continue;
390 }
391
392 if (sscanf(line, "pp_data->LinkCollectionArray[%u]", &coll_idx) == 1) {
393 if (pp_data->FirstByteOfLinkCollectionArray == 0 || pp_data->NumberLinkCollectionNodes == 0) {
394 fprintf(stderr, "Error reading pp_data file (%s): FirstByteOfLinkCollectionArray or NumberLinkCollectionNodes is 0 or not reported yet\n", line);
395 continue;
396 }
397 if (coll_idx >= pp_data->NumberLinkCollectionNodes) {
398 fprintf(stderr, "Error reading pp_data file (%s): the LinkCollection index (%u) is out of boundary (%hu)\n", line, coll_idx, pp_data->NumberLinkCollectionNodes);
399 continue;
400 }
401 phid_pp_link_collection_node pcoll = (phid_pp_link_collection_node)(((unsigned char*)&pp_data->caps[0]) + pp_data->FirstByteOfLinkCollectionArray);
402 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->LinkUsage = 0x%04hX\n", &coll_idx, &temp_usage) == 2) {
403 pcoll[coll_idx].LinkUsage = temp_usage;
404 continue;
405 }
406 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->LinkUsagePage = 0x%04hX\n", &coll_idx, &temp_usage) == 2) {
407 pcoll[coll_idx].LinkUsagePage = temp_usage;
408 continue;
409 }
410 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->Parent = %hu\n", &coll_idx, &temp_ushort) == 2) {
411 pcoll[coll_idx].Parent = temp_ushort;
412 continue;
413 }
414 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->NumberOfChildren = %hu\n", &coll_idx, &temp_ushort) == 2) {
415 pcoll[coll_idx].NumberOfChildren = temp_ushort;
416 continue;
417 }
418 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->NextSibling = %hu\n", &coll_idx, &temp_ushort) == 2) {
419 pcoll[coll_idx].NextSibling = temp_ushort;
420 continue;
421 }
422 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->FirstChild = %hu\n", &coll_idx, &temp_ushort) == 2) {
423 pcoll[coll_idx].FirstChild = temp_ushort;
424 continue;
425 }
426 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->CollectionType = %lu\n", &coll_idx, &temp_ulong) == 2) {
427 pcoll[coll_idx].CollectionType = temp_ulong;
428 continue;
429 }
430 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->IsAlias = %lu\n", &coll_idx, &temp_ulong) == 2) {
431 pcoll[coll_idx].IsAlias = temp_ulong;
432 continue;
433 }
434 if (sscanf(line, "pp_data->LinkCollectionArray[%u]->Reserved = %lu\n", &coll_idx, &temp_ulong) == 2) {
435 pcoll[coll_idx].Reserved = temp_ulong;
436 continue;
437 }
438 fprintf(stderr, "Ignoring unimplemented LinkCollectionArray field: %s", line);
439 continue;
440 }
441 }
442
443//end:
444 fclose(file);
445
446 if (pp_data == &static_pp_data) {
447 return NULL;
448 }
449
450 return pp_data;
451}
452
453static BOOLEAN read_hex_data_from_text_file(const char *filename, unsigned char *data_out, size_t data_size, size_t *actual_read)
454{
455 size_t read_index = 0;
456 FILE* file = NULL;
457 errno_t err = fopen_s(&file, filename, "r");
458 if (err != 0) {
459 fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, strerror(err));
460 return FALSE;
461 }
462
463 BOOLEAN result = TRUE;
464 unsigned int val;
465 char buf[16];
466 while (fscanf(file, "%15s", buf) == 1) {
467 if (sscanf(buf, "0x%X", &val) != 1) {
468 fprintf(stderr, "Invalid HEX text ('%s') file, got %s\n", filename, buf);
469 result = FALSE;
470 goto end;
471 }
472
473 if (read_index >= data_size) {
474 fprintf(stderr, "Buffer for file read is too small. Got only %zu bytes to read '%s'\n", data_size, filename);
475 result = FALSE;
476 goto end;
477 }
478
479 if (val > (unsigned char)-1) {
480 fprintf(stderr, "Invalid HEX text ('%s') file, got a value of: %u\n", filename, val);
481 result = FALSE;
482 goto end;
483 }
484
485 data_out[read_index] = (unsigned char) val;
486
487 read_index++;
488 }
489
490 if (!feof(file)) {
491 fprintf(stderr, "Invalid HEX text ('%s') file - failed to read all values\n", filename);
492 result = FALSE;
493 goto end;
494 }
495
496 *actual_read = read_index;
497
498end:
499 fclose(file);
500 return result;
501}
502
503
504int main(int argc, char* argv[])
505{
506 if (argc != 3) {
507 fprintf(stderr, "Expected 2 arguments for the test ('<>.pp_data' and '<>_expected.rpt_desc'), got: %d\n", argc - 1);
508 return EXIT_FAILURE;
509 }
510
511 printf("Checking: '%s' / '%s'\n", argv[1], argv[2]);
512
513 hidp_preparsed_data *pp_data = alloc_preparsed_data_from_file(argv[1]);
514 if (pp_data == NULL) {
515 return EXIT_FAILURE;
516 }
517
518 int result = EXIT_SUCCESS;
519
520 unsigned char report_descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
521
522 int res = hid_winapi_descriptor_reconstruct_pp_data(pp_data, report_descriptor, sizeof(report_descriptor));
523
524 if (res < 0) {
525 result = EXIT_FAILURE;
526 fprintf(stderr, "Failed to reconstruct descriptor");
527 goto end;
528 }
529 size_t report_descriptor_size = (size_t) res;
530
531 unsigned char expected_report_descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
532 size_t expected_report_descriptor_size = 0;
533 if (!read_hex_data_from_text_file(argv[2], expected_report_descriptor, sizeof(expected_report_descriptor), &expected_report_descriptor_size)) {
534 result = EXIT_FAILURE;
535 goto end;
536 }
537
538 if (report_descriptor_size == expected_report_descriptor_size) {
539 if (memcmp(report_descriptor, expected_report_descriptor, report_descriptor_size) == 0) {
540 printf("Reconstructed Report Descriptor matches the expected descriptor\n");
541 goto end;
542 }
543 else {
544 result = EXIT_FAILURE;
545 fprintf(stderr, "Reconstructed Report Descriptor has different content than expected\n");
546 }
547 }
548 else {
549 result = EXIT_FAILURE;
550 fprintf(stderr, "Reconstructed Report Descriptor has different size: %zu when expected %zu\n", report_descriptor_size, expected_report_descriptor_size);
551 }
552
553 printf(" Reconstructed Report Descriptor:\n");
554 for (int i = 0; i < res; i++) {
555 printf("0x%02X, ", report_descriptor[i]);
556 }
557 printf("\n");
558 fflush(stdout);
559
560end:
561 free(pp_data);
562 return result;
563}