SDL/test/testevdev.c

2250 lines
81 KiB
C
Raw Permalink Normal View History

/*
2024-01-02 00:15:26 +03:00
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 2020-2022 Collabora Ltd.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
/* Hack #1: avoid inclusion of SDL_main.h by SDL_internal.h */
#define SDL_main_h_
/* Hack #2: avoid dynapi renaming (must be done before #include <SDL3/SDL.h>) */
#include "../src/dynapi/SDL_dynapi.h"
#ifdef SDL_DYNAMIC_API
#undef SDL_DYNAMIC_API
#endif
Fix uses of undefined macro identifiers (-Wundef) * Fix -Wundef warnings due to use of unguarded SDL_LOADSO_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WINDOWS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_ANDROID * Fix -Wundef warnings due to use of unguarded SDL_LOADSO_DUMMY * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_COCOA * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_UIKIT * Fix -Wundef warnings due to use of unguarded SDL_TIMERS_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_EVENTS_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_TIMER_DUMMY * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_SENSOR_DISABLED * Fix -Wundef warnings due to use of unguarded __ANDROID__ * Fix -Wundef warnings due to use of unguarded __IOS__ * Fix -Wundef warnings due to use of unguarded EMULATE_CAS * Fix -Wundef warnings due to use of unguarded SDL_ATOMIC_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_THREADS_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_SNDIO * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_NETBSD * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_WASAPI * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DSOUND * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_HAIKU * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_COREAUDIO * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_AAUDIO * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_OPENSLES * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_ANDROID * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PS2 * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PSP * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_VITA * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_N3DS * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_NEON_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_ALTIVEC_BLITTERS * Fix -Wundef warnings due to use of unguarded __VITA__ * Fix -Wundef warnings due to use of unguarded __3DS__ * Fix -Wundef warnings due to use of unguarded SDL_DYNAPI_PROC_NO_VARARGS * Fix -Wundef warnings due to use of unguarded __APPLE__ * Fix -Wundef warnings due to use of unguarded __WINRT__ * Fix -Wundef warnings due to use of unguarded SDL_HIDAPI_DISABLED * Fix -Wundef warnings due to use of unguarded __TVOS__ * Fix -Wundef warnings due to use of unguarded HAVE_DRIVER_BACKEND * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_XINPUT * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_WGI * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_DINPUT * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_MFI * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_PS2 * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_PSP * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_VITA * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_N3DS * Fix -Wundef warnings due to use of unguarded __MACOS__ * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_D3D * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WINRT * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_RPI * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VITA_PVR_OGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_VIVANTE * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_D3D11 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_D3D12 * Fix -Wundef warnings due to use of unguarded SDL_RENDER_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_METAL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_PS2 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_PSP * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_VITA_GXM * Fix -Wundef warnings due to use of unguarded SDL_ARM_SIMD_BLITTERS * Fix -Wundef warnings due to use of unguarded SDL_ARM_NEON_BLITTERS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_HAIKU * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_PS2 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_PSP * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_VITA * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_N3DS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_KMSDRM * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_RISCOS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_NGAGE * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_METAL * Fix -Wundef warnings due to use of unguarded SDL_LSX_INTRINSICS * Fix -Wundef warnings due to use of unguarded HAVE_PTHREAD_NP_H * Fix -Wundef warnings due to use of unguarded __RISCOS__ * Fix -Wundef warnings due to use of unguarded FAKE_RECURSIVE_MUTEX * Fix -Wundef warnings due to use of unguarded USE_POSIX_SPAWN * textureData is only needed when SDL is built with YUV support * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_ALSA * Fix -Wundef warnings due to use of unguarded SDL_SSE3_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE4_2_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE4_1_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_AVX512F_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE2_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_AVX_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_AVX2_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_MMX_INTRINSICS * Fix -Wundef warnings due to use of unguarded HAVE_CLOCK_GETTIME * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DISK * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DUMMY * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_DUMMY * Fix -Wundef warnings due to use of unguarded HAVE_GCC_ATOMICS * Fix -Wundef warnings due to use of unguarded HAVE_GCC_SYNC_LOCK_TEST_AND_SET * Fix -Wundef warnings due to use of unguarded SDL_USE_LIBDBUS * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_JACK * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_VIRTUAL * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_LINUX * Fix -Wundef warnings due to use of unguarded HAVE_LIBC * Fix -Wundef warnings due to disabling SDL_LIBC * Fix -Wundef warnings due to use of unguarded HAVE_PLATFORM_BACKEND * Fix -Wundef warnings due to use of unguarded DEBUG * Fix -Wundef warnings due to use of unguarded HAVE_LINUX_INPUT_H * Fix -Werror=unused-variable when building with SDL_LIBC=OFF * Fix -Wundef warnings due to use of unguqrded SDL_USE_LIBUDEV * Use SDL alloc functions in libusb/hid.c * Fix -Wundef warnings due to use of unguarded HAVE_LIBUDEV_H * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VULKAN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_OFFSCREEN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_OGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_GLX * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_ES * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_ES2 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_OGL_ES2 * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_OSS * Remove SDL_AUDIO_DRIVER_SUNAUDIO reference since it is never set * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PIPEWIRE * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PULSEAUDIO * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XCURSOR * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XDBE * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XFIXES * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XINPUT2 * Fix -Wundef warnings due to use of unguarded #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH * Fix -Wundef warnings due to use of unguarded #if SDL_VIDEO_DRIVER_X11_XRANDR * Fix -Wundef warnings due to use of unguarded #if SDL_VIDEO_DRIVER_X11_XSCRNSAVER * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XSHAPE * Don't call XShape functions when XShape is diabled * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WAYLAND * Fix -Wundef warnings due to use of unuarded SDL_VIDEO_DRIVER_X11 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_RISCOS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_EGL * Disable array when compiled with SDL_EVENTS=OFF * Fix -Wundef warnings due to use of unguarded SDL_INPUT_LINUXEV * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PTHREAD * Fix -Wundef warnings due to use of unguarded SDL_THREAD_WINDOWS * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PS2 * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PSP * Fix -Wundef warnings due to use of unguarded SDL_THREAD_VITA * Fix -Wundef warnings due to use of unguarded SDL_THREAD_N3DS * Fix -Wundef warnings due to use of unguarded SDL_THREAD_STDCPP * Fix -Wundef warnings due to use of unguarded SDL_THREAD_NGAGE * Fix -Wundef warnings due to use of unguarded __WINDOWS__ * Fix -Wundef warnings due to use of unguarded __WINGDK__ * Fix -Wundef warnings due to use of unguarded __ANDROID__ * Fix -Wundef warnings due to use of unguarded SDL_THREAD_GENERIC_COND_SUFFIX * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VITA_PIB * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VITA_PVR * Fix -Wundef warnings due to use of unguarded SDL_FILE_DISABLED * Fix -Wundef warnings due to use of unguarded __XBOXONE__ * Fix -Wundef warnings due to use of unguarded __XBOXSERIES__ * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_WGL * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_QNX * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DISK * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_QNX * Fix -Wundef warnings due to use of unguarded DEBUG_RAZOR * Fix -Wundef warnings due to use of unguarded WINAPI_FAMILY_PHONE_APP * Fix -Wundef warnings due to use of unguarded SDL_MAC_NO_SANDBOX * Fix -Wundef warnings due to use of unguarded __(IPHONE|APPLETV|MAC)_OS_VERSION_MAX_ALLOWED * Fix C4090 warning ('function': different 'const' qualifiers) * ci: use -isystem for include dirs of pspdev toolchain * cmake: add -Wundef option * Fix remaining -Wundef warnings due to use of unguarded SDL_VIDEO_VULKAN and SDL_VIDEO_METAL * Fix -Wundef warnings due to use of unguarded __MACOS__ * DEBUG_CONVERT is guaranteed to be defined in src/audio/SDL_audiocvt.c * Fix -Wundef warnings due to use of unguarded HAVE_NANOSLEEP * Fix -Wundef warnings due to use of unguarded HAVE_DXGI_H * Fix -Wundef warnings due to use of unguarded HAVE_LINUX_INPUT_H * fix SDL_VIDEO_DRIVER_WAYLAND * fix SDL_VIDEO_DRIVER_X11 * Fix -Wundef warnings due to use of unguarded HAVE_MMDEVICEAPI_H * Fix -Wundef warnings due to use of unguarded HAVE_PTHREAD_SETNAME_NP * Fix -Wundef warnings due to use of unguarded HAVE_PTHREAD_SET_NAME_NP * Fix -Wundef warnings due to use of unguarded HAVE_SETJMP * Fix -Wundef warnings due to use of unguarded HAVE_SIGNAL_H * Fix -Wundef warnings due to use of unguarded HAVE_TPCSHRD_H * Fix -Wundef warnings due to use of unguarded MACOSX_COREAUDIO * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_DINPUT * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_IOKIT * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_XINPUT * Fix -Wundef warnings due to use of unguarded SDL_IPHONE_KEYBOARD * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_RAWINPUT * Fix -Wundef warnings due to use of unguarded SDL_POWER_ANDROID * Fix -Wundef warnings due to use of unguarded SDL_POWER_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_POWER_HAIKU * Fix -Wundef warnings due to use of unguarded SDL_POWER_LINUX * Fix -Wundef warnings due to use of unguarded SDL_POWER_MACOSX * Fix -Wundef warnings due to use of unguarded SDL_POWER_PSP * Fix -Wundef warnings due to use of unguarded SDL_POWER_UIKIT * Fix -Wundef warnings due to use of unguarded SDL_POWER_VITA * Fix -Wundef warnings due to use of unguarded SDL_POWER_WINDOWS * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PTHREAD_RECURSIVE_MUTEX * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_VIVANTE_VDK * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WAYLAND * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_CGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_EGL * Fix -Wundef warnings due to use of unguarded __MACOS__ * Fix -Wundef warnings due to use of unguarded __OpenBSD__ * Fix -Wundef warnings due to use of unguarded __FreeBSD__ * Fix -Wundef warnings due to use of unguarded __MWERKS__ * Fix -Wundef warnings due to use of unguarded __WIN32__ * Fix -Wundef warnings due to use of unguarded SDL_IPHONE_LAUNCHSCREEN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_ES2 * Remove unused HAVE_CONST, HAVE_INLINE and HAVE_VOLATILE * Revert "Use SDL alloc functions in libusb/hid.c" This reverts commit 847c64b00da12ca08bef9e947eb948e378eeaef8. * Handle FAKE_RECURSIVE_MUTEX in similar way as SDL2 * Don't use defined in macro
2023-03-30 00:49:01 +03:00
#define SDL_DYNAMIC_API 0
#ifndef NO_BUILD_CONFIG
#include "../src/SDL_internal.h"
#endif
/* Hack #3: undo Hack #1 */
#ifdef SDL_main_h_
#undef SDL_main_h_
#endif
#ifdef SDL_MAIN_NOIMPL
#undef SDL_MAIN_NOIMPL
#endif
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>
#include <stdio.h>
#include <string.h>
static int run_test(void);
/* FIXME: Need CMake tests for this */
Fix uses of undefined macro identifiers (-Wundef) * Fix -Wundef warnings due to use of unguarded SDL_LOADSO_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WINDOWS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_ANDROID * Fix -Wundef warnings due to use of unguarded SDL_LOADSO_DUMMY * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_COCOA * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_UIKIT * Fix -Wundef warnings due to use of unguarded SDL_TIMERS_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_EVENTS_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_TIMER_DUMMY * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_SENSOR_DISABLED * Fix -Wundef warnings due to use of unguarded __ANDROID__ * Fix -Wundef warnings due to use of unguarded __IOS__ * Fix -Wundef warnings due to use of unguarded EMULATE_CAS * Fix -Wundef warnings due to use of unguarded SDL_ATOMIC_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_THREADS_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_SNDIO * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_NETBSD * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_WASAPI * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DSOUND * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_HAIKU * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_COREAUDIO * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_AAUDIO * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_OPENSLES * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_ANDROID * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PS2 * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PSP * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_VITA * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_N3DS * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_NEON_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_ALTIVEC_BLITTERS * Fix -Wundef warnings due to use of unguarded __VITA__ * Fix -Wundef warnings due to use of unguarded __3DS__ * Fix -Wundef warnings due to use of unguarded SDL_DYNAPI_PROC_NO_VARARGS * Fix -Wundef warnings due to use of unguarded __APPLE__ * Fix -Wundef warnings due to use of unguarded __WINRT__ * Fix -Wundef warnings due to use of unguarded SDL_HIDAPI_DISABLED * Fix -Wundef warnings due to use of unguarded __TVOS__ * Fix -Wundef warnings due to use of unguarded HAVE_DRIVER_BACKEND * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_XINPUT * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_WGI * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_DINPUT * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_MFI * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_PS2 * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_PSP * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_VITA * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_N3DS * Fix -Wundef warnings due to use of unguarded __MACOS__ * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_D3D * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WINRT * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_RPI * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VITA_PVR_OGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_VIVANTE * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_D3D11 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_D3D12 * Fix -Wundef warnings due to use of unguarded SDL_RENDER_DISABLED * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_METAL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_PS2 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_PSP * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_VITA_GXM * Fix -Wundef warnings due to use of unguarded SDL_ARM_SIMD_BLITTERS * Fix -Wundef warnings due to use of unguarded SDL_ARM_NEON_BLITTERS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_HAIKU * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_PS2 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_PSP * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_VITA * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_N3DS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_KMSDRM * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_RISCOS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_NGAGE * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_METAL * Fix -Wundef warnings due to use of unguarded SDL_LSX_INTRINSICS * Fix -Wundef warnings due to use of unguarded HAVE_PTHREAD_NP_H * Fix -Wundef warnings due to use of unguarded __RISCOS__ * Fix -Wundef warnings due to use of unguarded FAKE_RECURSIVE_MUTEX * Fix -Wundef warnings due to use of unguarded USE_POSIX_SPAWN * textureData is only needed when SDL is built with YUV support * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_ALSA * Fix -Wundef warnings due to use of unguarded SDL_SSE3_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE4_2_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE4_1_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_AVX512F_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE2_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_AVX_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_AVX2_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_SSE_INTRINSICS * Fix -Wundef warnings due to use of unguarded SDL_MMX_INTRINSICS * Fix -Wundef warnings due to use of unguarded HAVE_CLOCK_GETTIME * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DISK * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DUMMY * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_DUMMY * Fix -Wundef warnings due to use of unguarded HAVE_GCC_ATOMICS * Fix -Wundef warnings due to use of unguarded HAVE_GCC_SYNC_LOCK_TEST_AND_SET * Fix -Wundef warnings due to use of unguarded SDL_USE_LIBDBUS * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_JACK * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_VIRTUAL * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_LINUX * Fix -Wundef warnings due to use of unguarded HAVE_LIBC * Fix -Wundef warnings due to disabling SDL_LIBC * Fix -Wundef warnings due to use of unguarded HAVE_PLATFORM_BACKEND * Fix -Wundef warnings due to use of unguarded DEBUG * Fix -Wundef warnings due to use of unguarded HAVE_LINUX_INPUT_H * Fix -Werror=unused-variable when building with SDL_LIBC=OFF * Fix -Wundef warnings due to use of unguqrded SDL_USE_LIBUDEV * Use SDL alloc functions in libusb/hid.c * Fix -Wundef warnings due to use of unguarded HAVE_LIBUDEV_H * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VULKAN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_OFFSCREEN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_OGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_GLX * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_ES * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_ES2 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_RENDER_OGL_ES2 * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_OSS * Remove SDL_AUDIO_DRIVER_SUNAUDIO reference since it is never set * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PIPEWIRE * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_PULSEAUDIO * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XCURSOR * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XDBE * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XFIXES * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XINPUT2 * Fix -Wundef warnings due to use of unguarded #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH * Fix -Wundef warnings due to use of unguarded #if SDL_VIDEO_DRIVER_X11_XRANDR * Fix -Wundef warnings due to use of unguarded #if SDL_VIDEO_DRIVER_X11_XSCRNSAVER * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_XSHAPE * Don't call XShape functions when XShape is diabled * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WAYLAND * Fix -Wundef warnings due to use of unuarded SDL_VIDEO_DRIVER_X11 * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_RISCOS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_EGL * Disable array when compiled with SDL_EVENTS=OFF * Fix -Wundef warnings due to use of unguarded SDL_INPUT_LINUXEV * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PTHREAD * Fix -Wundef warnings due to use of unguarded SDL_THREAD_WINDOWS * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PS2 * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PSP * Fix -Wundef warnings due to use of unguarded SDL_THREAD_VITA * Fix -Wundef warnings due to use of unguarded SDL_THREAD_N3DS * Fix -Wundef warnings due to use of unguarded SDL_THREAD_STDCPP * Fix -Wundef warnings due to use of unguarded SDL_THREAD_NGAGE * Fix -Wundef warnings due to use of unguarded __WINDOWS__ * Fix -Wundef warnings due to use of unguarded __WINGDK__ * Fix -Wundef warnings due to use of unguarded __ANDROID__ * Fix -Wundef warnings due to use of unguarded SDL_THREAD_GENERIC_COND_SUFFIX * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VITA_PIB * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_VITA_PVR * Fix -Wundef warnings due to use of unguarded SDL_FILE_DISABLED * Fix -Wundef warnings due to use of unguarded __XBOXONE__ * Fix -Wundef warnings due to use of unguarded __XBOXSERIES__ * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_WGL * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_QNX * Fix -Wundef warnings due to use of unguarded SDL_AUDIO_DRIVER_DISK * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_QNX * Fix -Wundef warnings due to use of unguarded DEBUG_RAZOR * Fix -Wundef warnings due to use of unguarded WINAPI_FAMILY_PHONE_APP * Fix -Wundef warnings due to use of unguarded SDL_MAC_NO_SANDBOX * Fix -Wundef warnings due to use of unguarded __(IPHONE|APPLETV|MAC)_OS_VERSION_MAX_ALLOWED * Fix C4090 warning ('function': different 'const' qualifiers) * ci: use -isystem for include dirs of pspdev toolchain * cmake: add -Wundef option * Fix remaining -Wundef warnings due to use of unguarded SDL_VIDEO_VULKAN and SDL_VIDEO_METAL * Fix -Wundef warnings due to use of unguarded __MACOS__ * DEBUG_CONVERT is guaranteed to be defined in src/audio/SDL_audiocvt.c * Fix -Wundef warnings due to use of unguarded HAVE_NANOSLEEP * Fix -Wundef warnings due to use of unguarded HAVE_DXGI_H * Fix -Wundef warnings due to use of unguarded HAVE_LINUX_INPUT_H * fix SDL_VIDEO_DRIVER_WAYLAND * fix SDL_VIDEO_DRIVER_X11 * Fix -Wundef warnings due to use of unguarded HAVE_MMDEVICEAPI_H * Fix -Wundef warnings due to use of unguarded HAVE_PTHREAD_SETNAME_NP * Fix -Wundef warnings due to use of unguarded HAVE_PTHREAD_SET_NAME_NP * Fix -Wundef warnings due to use of unguarded HAVE_SETJMP * Fix -Wundef warnings due to use of unguarded HAVE_SIGNAL_H * Fix -Wundef warnings due to use of unguarded HAVE_TPCSHRD_H * Fix -Wundef warnings due to use of unguarded MACOSX_COREAUDIO * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_DINPUT * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_IOKIT * Fix -Wundef warnings due to use of unguarded SDL_HAPTIC_XINPUT * Fix -Wundef warnings due to use of unguarded SDL_IPHONE_KEYBOARD * Fix -Wundef warnings due to use of unguarded SDL_JOYSTICK_RAWINPUT * Fix -Wundef warnings due to use of unguarded SDL_POWER_ANDROID * Fix -Wundef warnings due to use of unguarded SDL_POWER_EMSCRIPTEN * Fix -Wundef warnings due to use of unguarded SDL_POWER_HAIKU * Fix -Wundef warnings due to use of unguarded SDL_POWER_LINUX * Fix -Wundef warnings due to use of unguarded SDL_POWER_MACOSX * Fix -Wundef warnings due to use of unguarded SDL_POWER_PSP * Fix -Wundef warnings due to use of unguarded SDL_POWER_UIKIT * Fix -Wundef warnings due to use of unguarded SDL_POWER_VITA * Fix -Wundef warnings due to use of unguarded SDL_POWER_WINDOWS * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PTHREAD_RECURSIVE_MUTEX * Fix -Wundef warnings due to use of unguarded SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_VIVANTE_VDK * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_WAYLAND * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_CGL * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_EGL * Fix -Wundef warnings due to use of unguarded __MACOS__ * Fix -Wundef warnings due to use of unguarded __OpenBSD__ * Fix -Wundef warnings due to use of unguarded __FreeBSD__ * Fix -Wundef warnings due to use of unguarded __MWERKS__ * Fix -Wundef warnings due to use of unguarded __WIN32__ * Fix -Wundef warnings due to use of unguarded SDL_IPHONE_LAUNCHSCREEN * Fix -Wundef warnings due to use of unguarded SDL_VIDEO_OPENGL_ES2 * Remove unused HAVE_CONST, HAVE_INLINE and HAVE_VOLATILE * Revert "Use SDL alloc functions in libusb/hid.c" This reverts commit 847c64b00da12ca08bef9e947eb948e378eeaef8. * Handle FAKE_RECURSIVE_MUTEX in similar way as SDL2 * Don't use defined in macro
2023-03-30 00:49:01 +03:00
#if (defined(HAVE_LIBUDEV_H) || defined(SDL_JOYSTICK_LINUX)) && defined(HAVE_LINUX_INPUT_H)
#include <stdint.h>
#include "../src/core/linux/SDL_evdev_capabilities.h"
#include "../src/core/linux/SDL_evdev_capabilities.c"
static const struct
{
int code;
const char *name;
} device_classes[] = {
#define CLS(x) \
{ \
SDL_UDEV_DEVICE_##x, #x \
}
CLS(MOUSE),
CLS(KEYBOARD),
CLS(HAS_KEYS),
CLS(JOYSTICK),
CLS(SOUND),
CLS(TOUCHSCREEN),
CLS(ACCELEROMETER),
CLS(TOUCHPAD),
#undef CLS
{ 0, NULL }
};
typedef struct
{
const char *name;
const char *eviocgname;
const char *usb_vendor_name;
const char *usb_product_name;
uint16_t bus_type;
uint16_t vendor_id;
uint16_t product_id;
uint16_t version;
uint16_t usb_device_version;
uint8_t ev[(EV_MAX + 1) / 8];
uint8_t keys[(KEY_MAX + 1) / 8];
uint8_t abs[(ABS_MAX + 1) / 8];
uint8_t rel[(REL_MAX + 1) / 8];
uint8_t ff[(FF_MAX + 1) / 8];
uint8_t props[(INPUT_PROP_MAX + 1) / 8];
int expected;
const char *todo;
size_t hid_report_descriptor_length;
const unsigned char *hid_report_descriptor;
} GuessTest;
/*
* Test-cases for guessing a device type from its capabilities.
*
* The bytes in ev, etc. are in little-endian byte order
* Trailing zeroes can be omitted.
*
* The evemu-describe tool is a convenient way to add a test-case for
* a physically available device. To contribute new test-cases, see:
* https://github.com/libsdl-org/SDL/issues/7801#issuecomment-1589114910
*/
#define ZEROx4 0, 0, 0, 0
#define ZEROx8 ZEROx4, ZEROx4
#define FFx4 0xff, 0xff, 0xff, 0xff
#define FFx8 FFx4, FFx4
static unsigned char xbox_one_elite_2_hid_report_descriptor[] =
{
/* Generic Desktop / Game Pad, Generic Desktop / Keyboard */
0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01,
0x09, 0x01, 0xa1, 0x00, 0x09, 0x30, 0x09, 0x31,
0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x95,
0x02, 0x75, 0x10, 0x81, 0x02, 0xc0, 0x09, 0x01,
0xa1, 0x00, 0x09, 0x32, 0x09, 0x35, 0x15, 0x00,
0x27, 0xff, 0xff, 0x00, 0x00, 0x95, 0x02, 0x75,
0x10, 0x81, 0x02, 0xc0, 0x05, 0x02, 0x09, 0xc5,
0x15, 0x00, 0x26, 0xff, 0x03, 0x95, 0x01, 0x75,
0x0a, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75,
0x06, 0x95, 0x01, 0x81, 0x03, 0x05, 0x02, 0x09,
0xc4, 0x15, 0x00, 0x26, 0xff, 0x03, 0x95, 0x01,
0x75, 0x0a, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00,
0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01,
0x09, 0x39, 0x15, 0x01, 0x25, 0x08, 0x35, 0x00,
0x46, 0x3b, 0x01, 0x66, 0x14, 0x00, 0x75, 0x04,
0x95, 0x01, 0x81, 0x42, 0x75, 0x04, 0x95, 0x01,
0x15, 0x00, 0x25, 0x00, 0x35, 0x00, 0x45, 0x00,
0x65, 0x00, 0x81, 0x03, 0x05, 0x09, 0x19, 0x01,
0x29, 0x0f, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
0x95, 0x0f, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00,
0x75, 0x01, 0x95, 0x01, 0x81, 0x03, 0x05, 0x0c,
0x0a, 0xb2, 0x00, 0x15, 0x00, 0x25, 0x01, 0x95,
0x01, 0x75, 0x01, 0x81, 0x02, 0x15, 0x00, 0x25,
0x00, 0x75, 0x07, 0x95, 0x01, 0x81, 0x03, 0x05,
0x0c, 0x09, 0x01, 0xa1, 0x01, 0x0a, 0x85, 0x00,
0x15, 0x00, 0x26, 0xff, 0x00, 0x95, 0x01, 0x75,
0x08, 0x81, 0x02, 0x0a, 0x99, 0x00, 0x15, 0x00,
0x26, 0xff, 0x00, 0x95, 0x01, 0x75, 0x04, 0x81,
0x02, 0x15, 0x00, 0x25, 0x00, 0x95, 0x01, 0x75,
0x04, 0x81, 0x03, 0x0a, 0x81, 0x00, 0x15, 0x00,
0x26, 0xff, 0x00, 0x95, 0x01, 0x75, 0x04, 0x81,
0x02, 0x15, 0x00, 0x25, 0x00, 0x95, 0x01, 0x75,
0x04, 0x81, 0x03, 0xc0, 0x05, 0x0f, 0x09, 0x21,
0x85, 0x03, 0xa1, 0x02, 0x09, 0x97, 0x15, 0x00,
0x25, 0x01, 0x75, 0x04, 0x95, 0x01, 0x91, 0x02,
0x15, 0x00, 0x25, 0x00, 0x75, 0x04, 0x95, 0x01,
0x91, 0x03, 0x09, 0x70, 0x15, 0x00, 0x25, 0x64,
0x75, 0x08, 0x95, 0x04, 0x91, 0x02, 0x09, 0x50,
0x66, 0x01, 0x10, 0x55, 0x0e, 0x15, 0x00, 0x26,
0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02,
0x09, 0xa7, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
0x08, 0x95, 0x01, 0x91, 0x02, 0x65, 0x00, 0x55,
0x00, 0x09, 0x7c, 0x15, 0x00, 0x26, 0xff, 0x00,
0x75, 0x08, 0x95, 0x01, 0x91, 0x02, 0xc0, 0x05,
0x0c, 0x09, 0x01, 0x85, 0x0c, 0xa1, 0x01, 0x0a,
0x9e, 0x00, 0x15, 0x00, 0x26, 0xff, 0x00, 0x95,
0x01, 0x75, 0x08, 0x81, 0x02, 0x0a, 0xa1, 0x00,
0x15, 0x00, 0x26, 0xff, 0x00, 0x95, 0x01, 0x75,
0x08, 0x81, 0x02, 0x0a, 0xa2, 0x00, 0x15, 0x00,
0x26, 0xff, 0x00, 0x95, 0x01, 0x75, 0x08, 0x81,
0x02, 0x0a, 0xa3, 0x00, 0x15, 0x00, 0x26, 0xff,
0x00, 0x95, 0x01, 0x75, 0x08, 0x81, 0x02, 0xc0,
0xc0, 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x85,
0x05, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15,
0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81,
0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x03, 0x95,
0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05,
0x07, 0x19, 0x00, 0x29, 0x65, 0x81, 0x00, 0xc0,
};
SDL_COMPILE_TIME_ASSERT (xbox_one_elite_2, sizeof (xbox_one_elite_2_hid_report_descriptor) == 0720);
static unsigned char ps3_hid_report_descriptor[] =
{
/* Generic Desktop / Joystick */
0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
0xc0, 0x05, 0x01, 0x75, 0x08, 0x95, 0x27, 0x09,
0x01, 0x81, 0x02, 0x75, 0x08, 0x95, 0x30, 0x09,
0x01, 0x91, 0x02, 0x75, 0x08, 0x95, 0x30, 0x09,
0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
0xb1, 0x02, 0xc0, 0xc0, 0x00,
};
SDL_COMPILE_TIME_ASSERT (ps3, sizeof (ps3_hid_report_descriptor) == 149);
/* Same for Steam Deck LCD (jupiter) and OLED (galileo) */
static unsigned char steam_deck_mouse_hid_report_descriptor[] =
{
0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01,
0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x02,
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x02,
0x81, 0x02, 0x75, 0x06, 0x95, 0x01, 0x81, 0x01,
0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
0x25, 0x7f, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
0x95, 0x01, 0x09, 0x38, 0x81, 0x06, 0x05, 0x0c,
0x0a, 0x38, 0x02, 0x95, 0x01, 0x81, 0x06, 0xc0,
0xc0,
};
SDL_COMPILE_TIME_ASSERT (steam_deck_mouse,
sizeof (steam_deck_mouse_hid_report_descriptor) == 65);
/* Same for Steam Deck LCD (jupiter) and OLED (galileo) */
static unsigned char steam_deck_kb_hid_report_descriptor[] =
{
0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07,
0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01,
0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x81, 0x01,
0x19, 0x00, 0x29, 0x65, 0x15, 0x00, 0x25, 0x65,
0x75, 0x08, 0x95, 0x06, 0x81, 0x00, 0xc0,
};
SDL_COMPILE_TIME_ASSERT (steam_deck_oled_kb,
sizeof (steam_deck_kb_hid_report_descriptor) == 39);
static unsigned char steam_deck_lcd_js_hid_report_descriptor[] =
{
0x06, 0xff, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x15,
0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40,
0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0xb1, 0x02,
0xc0,
};
SDL_COMPILE_TIME_ASSERT (steam_deck_lcd_js,
sizeof (steam_deck_lcd_js_hid_report_descriptor) == 25);
static unsigned char steam_deck_oled_js_hid_report_descriptor[] =
{
0x06, 0xff, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x09,
0x02, 0x09, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00,
0x75, 0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x06,
0x09, 0x07, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
0x08, 0x95, 0x40, 0xb1, 0x02, 0xc0,
};
SDL_COMPILE_TIME_ASSERT (steam_deck_oled_js,
sizeof (steam_deck_oled_js_hid_report_descriptor) == 38);
static unsigned char vrs_pedals_hid_report_descriptor[] =
{
/* Generic Desktop / Joystick */
0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x05, 0x01,
0xa1, 0x02, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31,
0x09, 0x32, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00,
0x00, 0x35, 0x00, 0x47, 0xff, 0xff, 0x00, 0x00,
0x75, 0x10, 0x95, 0x03, 0x81, 0x02, 0x06, 0x00,
0xff, 0x09, 0x01, 0x95, 0x39, 0x75, 0x08, 0x26,
0xff, 0x00, 0x15, 0x00, 0x81, 0x02, 0xc0, 0x06,
0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x64,
0x95, 0x3f, 0x75, 0x08, 0x26, 0xff, 0x00, 0x15,
0x00, 0x09, 0x01, 0x91, 0x02, 0x85, 0x65, 0x95,
0x3f, 0x75, 0x08, 0x26, 0xff, 0x00, 0x15, 0x00,
0x09, 0x01, 0x81, 0x02, 0xc0, 0xc0,
};
SDL_COMPILE_TIME_ASSERT (vrs_pedals, sizeof (vrs_pedals_hid_report_descriptor) == 0136);
static unsigned char thinkpad_usb_keyboard_hid_report_descriptor[] =
{
/* Generic Desktop / Keyboard */
0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07,
0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01,
0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0x95, 0x08,
0x75, 0x01, 0x81, 0x01, 0x05, 0x08, 0x19, 0x01,
0x29, 0x03, 0x95, 0x03, 0x75, 0x01, 0x91, 0x02,
0x95, 0x01, 0x75, 0x05, 0x91, 0x01, 0x05, 0x07,
0x19, 0x00, 0x2a, 0xff, 0x00, 0x15, 0x00, 0x26,
0xff, 0x00, 0x95, 0x06, 0x75, 0x08, 0x81, 0x00,
0xc0,
};
SDL_COMPILE_TIME_ASSERT (thinkpad_usb_keyboard, sizeof (thinkpad_usb_keyboard_hid_report_descriptor) == 65);
static unsigned char thinkpad_usb_trackpoint_hid_report_descriptor[] =
{
/* Generic Desktop / Mouse, Generic Desktop / System Control,
* Consumer Devices / Consumer Control */
0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x01,
0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01,
0x29, 0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x03,
0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05,
0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31,
0x15, 0x81, 0x25, 0x7f, 0x95, 0x02, 0x75, 0x08,
0x81, 0x06, 0xc0, 0xc0, 0x05, 0x01, 0x09, 0x80,
0xa1, 0x01, 0x85, 0x02, 0x05, 0x01, 0x15, 0x00,
0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x19, 0x81,
0x29, 0x88, 0x81, 0x02, 0xc0, 0x05, 0x0c, 0x09,
0x01, 0xa1, 0x01, 0x85, 0x03, 0x95, 0x08, 0x75,
0x01, 0x15, 0x00, 0x25, 0x01, 0x09, 0xe9, 0x09,
0xea, 0x09, 0xe2, 0x09, 0xb7, 0x09, 0xcd, 0x09,
0xb5, 0x09, 0xb6, 0x0a, 0x94, 0x01, 0x81, 0x02,
0x09, 0x03, 0xa1, 0x02, 0x05, 0x09, 0x19, 0x10,
0x29, 0x17, 0x81, 0x02, 0x05, 0x09, 0x19, 0x18,
0x29, 0x1f, 0x81, 0x02, 0xc0, 0x05, 0x08, 0x95,
0x02, 0x09, 0x09, 0x09, 0x21, 0x91, 0x02, 0x95,
0x01, 0x75, 0x06, 0x91, 0x03, 0xc0, 0x06, 0x01,
0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x04, 0x95,
0x01, 0x75, 0x08, 0x15, 0x00, 0x26, 0xff, 0x00,
0x09, 0x20, 0xb1, 0x03, 0x09, 0x21, 0xb1, 0x03,
0x09, 0x22, 0xb1, 0x03, 0x09, 0x23, 0xb1, 0x03,
0xc0,
};
SDL_COMPILE_TIME_ASSERT (thinkpad_usb_trackpoint, sizeof (thinkpad_usb_trackpoint_hid_report_descriptor) == 185);
static unsigned char heusinkveld_pedals_hid_report_descriptor[] =
{
/* Generic Desktop / Joystick */
0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x09, 0x33,
0x09, 0x34, 0x09, 0x35, 0x15, 0x00, 0x26, 0xff,
0x0f, 0x85, 0x01, 0x75, 0x10, 0x95, 0x03, 0x81,
0x02, 0x09, 0x00, 0x75, 0x10, 0x95, 0x06, 0x82,
0x01, 0x01, 0x85, 0x02, 0x75, 0x10, 0x95, 0x03,
0x09, 0x00, 0x09, 0x00, 0xb1, 0x02, 0x85, 0x03,
0x75, 0x08, 0x95, 0x03, 0x09, 0x00, 0x82, 0x01,
0x01, 0xc0,
};
SDL_COMPILE_TIME_ASSERT (heusinkveld_pedals, sizeof (heusinkveld_pedals_hid_report_descriptor) == 072);
static unsigned char fanatec_handbrake_hid_report_descriptor[] =
{
/* Generic Desktop / Joystick */
0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x15, 0x00,
0x26, 0xff, 0x00, 0x95, 0x01, 0x75, 0x08, 0x09,
0x30, 0x81, 0x02, 0x06, 0x00, 0xff, 0x09, 0x01,
0x95, 0x03, 0x81, 0x02, 0x06, 0x00, 0xff, 0x09,
0x01, 0x95, 0x02, 0x91, 0x02, 0xc0,
};
SDL_COMPILE_TIME_ASSERT (fanatec_handbrake, sizeof (fanatec_handbrake_hid_report_descriptor) == 046);
static unsigned char xpadneo09_xb1s_hid_report_descriptor[] =
{
0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01,
0x09, 0x01, 0xa1, 0x00, 0x09, 0x30, 0x09, 0x31,
0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x95,
0x02, 0x75, 0x10, 0x81, 0x02, 0xc0, 0x09, 0x01,
0xa1, 0x00, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00,
0x27, 0xff, 0xff, 0x00, 0x00, 0x95, 0x02, 0x75,
0x10, 0x81, 0x02, 0xc0, 0x05, 0x01, 0x09, 0x32,
0x15, 0x00, 0x26, 0xff, 0x03, 0x95, 0x01, 0x75,
0x0a, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75,
0x06, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09,
0x35, 0x15, 0x00, 0x26, 0xff, 0x03, 0x95, 0x01,
0x75, 0x0a, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00,
0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01,
0x09, 0x39, 0x15, 0x01, 0x25, 0x08, 0x35, 0x00,
0x46, 0x3b, 0x01, 0x66, 0x14, 0x00, 0x75, 0x04,
0x95, 0x01, 0x81, 0x42, 0x75, 0x04, 0x95, 0x01,
0x15, 0x00, 0x25, 0x00, 0x35, 0x00, 0x45, 0x00,
0x65, 0x00, 0x81, 0x03, 0x05, 0x09, 0x19, 0x01,
0x29, 0x0c, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
0x95, 0x0c, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00,
0x75, 0x01, 0x95, 0x04, 0x81, 0x03, 0x05, 0x0c,
0x0a, 0xb2, 0x00, 0x15, 0x00, 0x25, 0x01, 0x95,
0x01, 0x75, 0x01, 0x81, 0x02, 0x15, 0x00, 0x25,
0x00, 0x75, 0x07, 0x95, 0x01, 0x81, 0x03, 0x05,
0x0f, 0x09, 0x21, 0x85, 0x03, 0xa1, 0x02, 0x09,
0x97, 0x15, 0x00, 0x25, 0x01, 0x75, 0x04, 0x95,
0x01, 0x91, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75,
0x04, 0x95, 0x01, 0x91, 0x03, 0x09, 0x70, 0x15,
0x00, 0x25, 0x64, 0x75, 0x08, 0x95, 0x04, 0x91,
0x02, 0x09, 0x50, 0x66, 0x01, 0x10, 0x55, 0x0e,
0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
0x01, 0x91, 0x02, 0x09, 0xa7, 0x15, 0x00, 0x26,
0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02,
0x65, 0x00, 0x55, 0x00, 0x09, 0x7c, 0x15, 0x00,
0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91,
0x02, 0xc0, 0xc0,
};
SDL_COMPILE_TIME_ASSERT (xpadneo09_xb1s, sizeof (xpadneo09_xb1s_hid_report_descriptor) == 283);
/* Test-cases derived from real devices or from Linux kernel source */
/* *INDENT-OFF* */ /* clang-format off */
static const GuessTest guess_tests[] =
{
{
.name = "Xbox 360 wired USB controller",
.eviocgname = "Microsoft X-Box 360 pad",
.usb_vendor_name = "©Microsoft Corporation",
.usb_product_name = "Controller",
/* 8BitDo N30 Pro 2 v0114 via USB-C (with the xpad driver) is
* reported as 0003:045e:028e v0114, and is functionally equivalent */
.bus_type = 0x0003,
.vendor_id = 0x045e,
.product_id = 0x028e,
.version = 0x0114,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, FF */
.ev = { 0x0b, 0x00, 0x20 },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{
.name = "X-Box One Elite",
.bus_type = 0x0003,
.vendor_id = 0x045e,
.product_id = 0x02e3,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{ /* Reference: https://github.com/libsdl-org/SDL/issues/7814 */
.name = "X-Box One Elite 2 via USB",
/* The same physical device via Bluetooth, 0005:045e:0b22 v0517,
* is reported differently (below). */
/* Version 0407 is functionally equivalent. */
.bus_type = 0x0003,
.vendor_id = 0x045e,
.product_id = 0x0b00,
.version = 0x0511,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, FF */
.ev = { 0x0b, 0x00, 0x20 },
/* XY (left stick), RX/RY (right stick), Z/RZ (triggers), HAT0 (dpad) */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* BTN_TRIGGER_HAPPY5 up to BTN_TRIGGER_HAPPY8 inclusive are the
* back buttons (paddles) */
/* 0x2c0 */ 0xf0,
},
},
{ /* Reference: https://github.com/libsdl-org/SDL/issues/7814 */
.name = "X-Box One Elite 2 via Bluetooth",
/* The same physical device via USB, 0003:045e:0b00 v0511,
* is reported differently (above). */
.bus_type = 0x0003,
.vendor_id = 0x045e,
.product_id = 0x0b22,
.version = 0x0517,
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY, ABS, FF */
.ev = { 0x0b, 0x00, 0x20 },
/* Android-style mapping:
* XY (left stick), Z/RZ (right stick), GAS/BRAKE (triggers), HAT0 (dpad) */
.abs = { 0x27, 0x06, 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx8,
/* KEY_RECORD is advertised but isn't generated in practice */
/* 0x80 */ ZEROx4, 0x80, 0x00, 0x00, 0x00,
/* KEY_UNKNOWN (240) is reported for the profile selector and all
* four back buttons (paddles) */
/* 0xc0 */ ZEROx4, 0x00, 0x00, 0x01, 0x00,
/* ABXY, TL, TR, TL2, TR2, SELECT, START, MODE, THUMBL,
* THUMBR have their obvious meanings; C and Z are also
* advertised, but are not generated in practice. */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x7f,
},
.hid_report_descriptor_length = sizeof (xbox_one_elite_2_hid_report_descriptor),
.hid_report_descriptor = &xbox_one_elite_2_hid_report_descriptor[0],
},
{
.name = "X-Box One S via Bluetooth",
.bus_type = 0x0005,
.vendor_id = 0x045e,
.product_id = 0x02e0,
.version = 0x1130,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{
.name = "X-Box One S wired",
.bus_type = 0x0003,
.vendor_id = 0x045e,
.product_id = 0x02ea,
.version = 0x0301,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{
.name = "X-Box One S via xpadneo 0.9.x",
/* Reference: https://github.com/libsdl-org/SDL/issues/7823 */
.eviocgname = "Xbox Wireless Controller",
.bus_type = 0x0005,
.vendor_id = 0x045e,
.product_id = 0x028e,
.version = 0x1130,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC, FF */
.ev = { 0x1b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y
* plus MISC as a deprecated axis reporting (rz - z) */
.abs = { 0x3f, 0x00, 0x03, 0x00, 0x00, 0x01 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* BTN_TRIGGER_HAPPY33 up to BTN_TRIGGER_HAPPY36 inclusive:
* used to represent the current profile */
/* 0x2c0 */ ZEROx4, 0xf0,
},
.hid_report_descriptor_length = sizeof (xpadneo09_xb1s_hid_report_descriptor),
.hid_report_descriptor = &xpadneo09_xb1s_hid_report_descriptor[0],
},
{
.name = "DualSense (PS5) - gamepad",
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x0ce6,
.version = 0x111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, select, start, mode, thumbl,
* thumbr; note that C and Z don't physically exist */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x7f,
},
},
{
.name = "DualSense (PS5) v8111 - gamepad",
.eviocgname = "Sony Interactive Entertainment Wireless Controller",
.usb_vendor_name = "Sony Interactive Entertainment",
.usb_product_name = "Wireless Controller",
/* Same physical device via Bluetooth is 0005:054c:0ce6 v8100
* and EVIOCGNAME is just "Wireless Controller", otherwise equivalent */
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x0ce6,
.version = 0x8111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
},
},
{
.name = "DualShock 4 - gamepad",
/* EVIOCGNAME is just "Wireless Controller" when seen via Bluetooth */
.eviocgname = "Sony Interactive Entertainment Wireless Controller",
.usb_vendor_name = "Sony Interactive Entertainment",
.usb_product_name = "Wireless Controller",
/* Same physical device via Bluetooth is 0005:054c:09cc v8100,
* but otherwise equivalent */
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x09cc,
.version = 0x8111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC, FF */
/* Some versions only have 0x0b, SYN, KEY, ABS, like the
* Bluetooth example below */
.ev = { 0x1b, 0x00, 0x20 },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
},
},
{
.name = "DualShock 4 - gamepad via Bluetooth (unknown version)",
.bus_type = 0x0005,
.vendor_id = 0x054c,
.product_id = 0x09cc,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
},
},
{
.name = "DualShock 4 - touchpad",
/* EVIOCGNAME is just "Wireless Controller Touchpad" when seen via Bluetooth */
.eviocgname = "Sony Interactive Entertainment Wireless Controller Touchpad",
.usb_vendor_name = "Sony Interactive Entertainment",
.usb_product_name = "Wireless Controller",
/* Same physical device via Bluetooth is 0005:054c:09cc v8100 and is
* functionally equivalent. */
/* DualSense (PS5), 0003:054c:0ce6 v8111, is functionally equivalent.
* Same physical device via Bluetooth is 0005:054c:0ce6 v8100 and also
* functionally equivalent. */
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x09cc,
.version = 0x8111,
.expected = SDL_UDEV_DEVICE_TOUCHPAD,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, multitouch */
.abs = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x02 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* Left mouse button */
/* 0x100 */ 0x00, 0x00, 0x01, 0x00, ZEROx4,
/* BTN_TOOL_FINGER and some multitouch stuff */
/* 0x140 */ 0x20, 0x24, 0x00, 0x00
},
/* POINTER, BUTTONPAD */
.props = { 0x05 },
},
{
.name = "DualShock 4 - accelerometer",
/* EVIOCGNAME is just "Wireless Controller Motion Sensors" when seen via Bluetooth */
.eviocgname = "Sony Interactive Entertainment Wireless Controller Motion Sensors",
.usb_vendor_name = "Sony Interactive Entertainment",
.usb_product_name = "Wireless Controller",
/* Same physical device via Bluetooth is 0005:054c:09cc v8100 and is
* functionally equivalent. */
/* DualSense (PS5), 0003:054c:0ce6 v8111, is functionally equivalent.
* Same physical device via Bluetooth is 0005:054c:0ce6 v8100 and also
* functionally equivalent. */
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x09cc,
.version = 0x8111,
.expected = SDL_UDEV_DEVICE_ACCELEROMETER,
/* SYN, ABS, MSC */
.ev = { 0x19 },
/* X, Y, Z, RX, RY, RZ */
.abs = { 0x3f },
/* ACCELEROMETER */
.props = { 0x40 },
},
{
.name = "DualShock 4 via USB dongle",
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x0ba0,
.version = 0x8111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, ABS, KEY */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
},
},
{
.name = "DualShock 3 - gamepad",
.eviocgname = "Sony PLAYSTATION(R)3 Controller",
.usb_vendor_name = "Sony",
.usb_product_name = "PLAYSTATION(R)3 Controller",
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x0268,
.version = 0x8111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC, FF */
.ev = { 0x1b, 0x00, 0x20 },
/* X, Y, Z, RX, RY, RZ */
.abs = { 0x3f },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* Digital dpad */
/* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00,
},
.hid_report_descriptor_length = sizeof (ps3_hid_report_descriptor),
.hid_report_descriptor = &ps3_hid_report_descriptor[0],
},
{
.name = "DualShock 3 - accelerometer",
.eviocgname = "Sony PLAYSTATION(R)3 Controller Motion Sensors",
.usb_vendor_name = "Sony",
.usb_product_name = "PLAYSTATION(R)3 Controller",
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x0268,
.expected = SDL_UDEV_DEVICE_ACCELEROMETER,
/* SYN, ABS */
.ev = { 0x09 },
/* X, Y, Z */
.abs = { 0x07 },
/* ACCELEROMETER */
.props = { 0x40 },
.hid_report_descriptor_length = sizeof (ps3_hid_report_descriptor),
.hid_report_descriptor = &ps3_hid_report_descriptor[0],
},
{
.name = "Steam Controller - gamepad",
.bus_type = 0x0003,
.vendor_id = 0x28de,
.product_id = 0x1142,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RX, RY, HAT0X, HAT0Y, HAT2X, HAT2Y */
.abs = { 0x1b, 0x00, 0x33 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL, THUMBR, joystick THUMB, joystick THUMB2 */
/* 0x100 */ ZEROx4, 0x06, 0x00, 0xdb, 0x7f,
/* GEAR_DOWN, GEAR_UP */
/* 0x140 */ 0x00, 0x00, 0x03, 0x00, ZEROx4,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* Digital dpad */
/* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00,
},
},
{
/* Present to support lizard mode, even if no Steam Controller
* is connected */
.name = "Steam Controller - dongle",
.bus_type = 0x0003,
.vendor_id = 0x28de,
.product_id = 0x1142,
.expected = (SDL_UDEV_DEVICE_HAS_KEYS
| SDL_UDEV_DEVICE_KEYBOARD
| SDL_UDEV_DEVICE_MOUSE),
/* SYN, KEY, REL, MSC, LED, REP */
.ev = { 0x17, 0x00, 0x12 },
/* X, Y, mouse wheel, high-res mouse wheel */
.rel = { 0x03, 0x09 },
.keys = {
/* 0x00 */ 0xfe, 0xff, 0xff, 0xff, FFx4,
/* 0x40 */ 0xff, 0xff, 0xcf, 0x01, 0xdf, 0xff, 0x80, 0xe0,
/* 0x80 */ ZEROx8,
/* 0xc0 */ ZEROx8,
/* 0x100 */ 0x00, 0x00, 0x1f, 0x00, ZEROx4,
},
},
{
.name = "Steam Deck - mouse",
/* This is the LCD model (jupiter).
* Steam Deck OLED (galileo, possibly pre-production) has
* .eviocgname = "Valve Software Steam Controller"
* .version = 0x0110
* .usb_device_version = 0x0300
* but is otherwise equivalent.
*/
.eviocgname = "Valve Software Steam Deck Controller",
.usb_vendor_name = "Valve Software",
.usb_product_name = "Steam Deck Controller",
.bus_type = 0x0003,
.vendor_id = 0x28de,
.product_id = 0x1205,
.version = 0x011,
.usb_device_version = 0x0200,
/* SYN, KEY, REL, MSC */
.ev = { 0x17 },
/* X, Y, mouse wheel v/h, high-res mouse wheel v/h */
.rel = { 0x43, 0x19 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* left/right mouse button */
/* 0x100 */ 0x00, 0x00, 0x03, 0x00, ZEROx4,
},
.expected = SDL_UDEV_DEVICE_MOUSE,
.hid_report_descriptor_length = sizeof (steam_deck_mouse_hid_report_descriptor),
.hid_report_descriptor = &steam_deck_mouse_hid_report_descriptor[0],
},
{
.name = "Steam Deck - keyboard",
/* This is the LCD model (jupiter).
* Steam Deck OLED (galileo, possibly pre-production) has
* .eviocgname = "Valve Software Steam Controller"
* .version = 0x0110
* .usb_device_version = 0x0300
* but is otherwise equivalent.
*/
.eviocgname = "Valve Software Steam Deck Controller",
.usb_vendor_name = "Valve Software",
.usb_product_name = "Steam Deck Controller",
.bus_type = 0x0003,
.vendor_id = 0x28de,
.product_id = 0x1205,
.version = 0x0110,
.usb_device_version = 0x0300,
/* SYN, KEY, MSC, REP */
.ev = { 0x13, 0x00, 0x10 },
.keys = {
/* 0x00 */ 0xfe, 0xff, 0xff, 0xff, FFx4,
/* 0x40 */ 0xff, 0xff, 0xcf, 0x01, 0xdf, 0xff, 0x80, 0xe0,
},
.expected = SDL_UDEV_DEVICE_KEYBOARD | SDL_UDEV_DEVICE_HAS_KEYS,
.hid_report_descriptor_length = sizeof (steam_deck_kb_hid_report_descriptor),
.hid_report_descriptor = &steam_deck_kb_hid_report_descriptor[0],
},
{
.name = "Steam Deck LCD - gamepad",
.eviocgname = "Valve Software Steam Deck Controller",
.usb_vendor_name = "Valve Software",
.usb_product_name = "Steam Deck Controller",
.bus_type = 0x0003,
.vendor_id = 0x28de,
.product_id = 0x1205,
.version = 0x0111,
.usb_device_version = 0x0200,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* TODO: The data I have for Steam Deck LCD didn't seem to have
* an evdev device available, so this is extrapolated from
* kernel source code as being the same as the OLED model
* (the kernel driver doesn't distinguish). */
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RX, RY, hat 0-2 x/y */
.abs = { 0x1b, 0x00, 0x3f },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 0x120 0x46: joystick THUMB, THUMB2, BASE */
/* 0x130 0xdb: gamepad ABXY, TL/TR */
/* 0x138 0x7f: gamepad TL2/TR2, SELECT/START, MODE, THUMBL/R */
/* 0x100 */ ZEROx4, 0x46, 0x00, 0xdb, 0x7f,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x220 0x0f: dpad up/down/left/right */
/* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* 0x2c0 0x0f: joystick TRIGGER_HAPPY1..TRIGGER_HAPPY4 */
/* 0x2c0 */ 0x0f,
},
.hid_report_descriptor_length = sizeof (steam_deck_lcd_js_hid_report_descriptor),
.hid_report_descriptor = &steam_deck_lcd_js_hid_report_descriptor[0],
},
{
.name = "Steam Deck OLED - gamepad",
.eviocgname = "Valve Software Steam Controller",
.usb_vendor_name = "Valve Software",
.usb_product_name = "Steam Controller",
.bus_type = 0x0003,
.vendor_id = 0x28de,
.product_id = 0x1205,
.version = 0x0110,
.usb_device_version = 0x0300,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RX, RY, hat 0-2 x/y */
.abs = { 0x1b, 0x00, 0x3f },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 0x120 0x46: joystick THUMB, THUMB2, BASE */
/* 0x130 0xdb: gamepad ABXY, TL/TR */
/* 0x138 0x7f: gamepad TL2/TR2, SELECT/START, MODE, THUMBL/R */
/* 0x100 */ ZEROx4, 0x46, 0x00, 0xdb, 0x7f,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x220 0x0f: dpad up/down/left/right */
/* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* 0x2c0 0x0f: joystick TRIGGER_HAPPY1..TRIGGER_HAPPY4 */
/* 0x2c0 */ 0x0f,
},
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.hid_report_descriptor_length = sizeof (steam_deck_oled_js_hid_report_descriptor),
.hid_report_descriptor = &steam_deck_oled_js_hid_report_descriptor[0],
},
{
.name = "Steam Input virtual controller",
.eviocgname = "Microsoft X-Box 360 pad 0",
.bus_type = 0x0003,
.vendor_id = 0x28de,
.product_id = 0x11ff,
.version = 0x0001,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, FF */
.ev = { 0x0b, 0x00, 0x20 },
/* XYZ, RXYZ, hat 0 */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 0x130 0xdb: gamepad ABXY, TL/TR */
/* 0x138 0x7f: gamepad SELECT/START, MODE, THUMBL/R */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{
.name = "Guitar Hero for PS3",
/* SWITCH CO.,LTD. Controller (Dinput) off-brand N64-style USB controller
* 0003:2563:0575 v0111 is functionally equivalent.
* https://linux-hardware.org/?id=usb:2563-0575 reports the same IDs as
* ShenZhen ShanWan Technology ZD-V+ Wired Gaming Controller */
.bus_type = 0x0003,
.vendor_id = 0x12ba,
.product_id = 0x0100,
.version = 0x0110,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RZ, HAT0X, HAT0Y */
.abs = { 0x27, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x1f,
},
},
{
.name = "G27 Racing Wheel, 0003:046d:c29b v0111",
.bus_type = 0x0003,
.vendor_id = 0x046d,
.product_id = 0xc29b,
.version = 0x0111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RZ, HAT0X, HAT0Y */
.abs = { 0x27, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 16 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE,
* BASE2..BASE6, unregistered event codes 0x12c-0x12e, DEAD */
/* 0x100 */ ZEROx4, 0xff, 0xff, 0x00, 0x00,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* TRIGGER_HAPPY1..TRIGGER_HAPPY7 */
/* 0x2c0 */ 0x7f,
},
},
{
.name = "Logitech Driving Force, 0003:046d:c294 v0100",
.bus_type = 0x0003,
.vendor_id = 0x046d,
.product_id = 0xc294,
.version = 0x0100,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RZ, HAT0X, HAT0Y */
.abs = { 0x23, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 12 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE,
* BASE2..BASE6 */
/* 0x100 */ ZEROx4, 0xff, 0x0f, 0x00, 0x00,
},
},
{
.name = "Logitech Dual Action",
.bus_type = 0x0003,
.vendor_id = 0x046d,
.product_id = 0xc216,
.version = 0x0110,
/* Logitech RumblePad 2 USB, 0003:046d:c218 v0110, is the same
* except for having force feedback, which we don't use in our
* heuristic */
/* Jess Tech GGE909 PC Recoil Pad, 0003:0f30:010b v0110, is the same */
/* 8BitDo SNES30 via USB, 0003:2dc8:ab20 v0110, is the same;
* see below for the same physical device via Bluetooth,
* 0005:2dc8:2840 v0100 */
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RZ, HAT0X, HAT0Y */
.abs = { 0x27, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 12 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE,
* BASE2..BASE6 */
/* 0x100 */ ZEROx4, 0xff, 0x0f, 0x00, 0x00,
},
},
{
.name = "8BitDo SNES30 v0100 via Bluetooth",
.eviocgname = "8Bitdo SNES30 GamePad",
/* The same physical device via USB, 0003:2dc8:ab20 v0110,
* is reported differently (above). */
/* 8BitDo NES30 Pro (aka N30 Pro) via Bluetooth, 0005:2dc8:3820 v0100,
* is functionally equivalent; but the same physical device via USB,
* 0003:2dc8:9001 v0111, matches N30 Pro 2 v0111. */
.bus_type = 0x0005,
.vendor_id = 0x2dc8,
.product_id = 0x2840,
.version = 0x0100,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC */
.ev = { 0x1b },
/* XYZ, RZ, GAS, BRAKE, HAT0X, HAT0Y */
.abs = { 0x27, 0x06, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE, THUMBL, THUMBR,
* and an unassigned button code */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0xff,
},
},
{
.name = "Saitek ST290 Pro flight stick",
.bus_type = 0x0003,
.vendor_id = 0x06a3,
.product_id = 0x0160, /* 0x0460 seems to be the same */
.version = 0x0100,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC */
.ev = { 0x1b },
/* X, Y, Z, RZ, HAT0X, HAT0Y */
.abs = { 0x27, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE */
/* 0x100 */ ZEROx4, 0x3f, 0x00, 0x00, 0x00,
},
},
{
.name = "Saitek X52 Pro Flight Control System",
.bus_type = 0x0003,
.vendor_id = 0x06a3,
.product_id = 0x0762,
.version = 0x0111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.ev = { 0x0b },
/* XYZ, RXYZ, throttle, hat0, MISC, unregistered event code 0x29 */
.abs = { 0x7f, 0x00, 0x03, 0x00, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 16 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE,
* BASE2..BASE6, unregistered event codes 0x12c-0x12e, DEAD */
/* 0x100 */ ZEROx4, 0xff, 0xff, 0x00, 0x00,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* TRIGGER_HAPPY1..TRIGGER_HAPPY23 */
/* 0x2c0 */ 0xff, 0xff, 0x7f,
},
},
{
.name = "Logitech Extreme 3D",
.bus_type = 0x0003,
.vendor_id = 0x046d,
.product_id = 0xc215,
.version = 0x0110,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC */
.ev = { 0x0b },
/* X, Y, RZ, throttle, hat 0 */
.abs = { 0x63, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 12 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE,
* BASE2..BASE6 */
/* 0x100 */ ZEROx4, 0xff, 0x0f, 0x00, 0x00,
},
},
{
.name = "Hori Real Arcade Pro VX-SA",
.bus_type = 0x0003,
.vendor_id = 0x24c6,
.product_id = 0x5501,
.version = 0x0533,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, hat 0 */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{
/* https://github.com/ValveSoftware/steam-devices/pull/42
* PS4 mode is functionally equivalent, but with product ID 0x011c
* and version 0x1101. */
.name = "Hori Fighting Stick Alpha - PS5 mode",
.bus_type = 0x0003, /* USB */
.vendor_id = 0x0f0d, /* Hori Co., Ltd. */
.product_id = 0x0184, /* HORI FIGHTING STICK α (PS5 mode) */
.version = 0x0111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC */
.ev = { 0x1b },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x3f,
},
},
{ /* https://github.com/ValveSoftware/steam-devices/pull/42 */
.name = "Hori Fighting Stick Alpha - PC mode",
.bus_type = 0x0003, /* USB */
.vendor_id = 0x0f0d, /* Hori Co., Ltd. */
.product_id = 0x011e, /* HORI FIGHTING STICK α (PC mode) */
.version = 0x0116,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, FF */
.ev = { 0x0b, 0x00, 0x20 },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{ /* https://github.com/ValveSoftware/steam-devices/issues/29 */
.name = "HORIPAD S for Nintendo",
.bus_type = 0x0003, /* USB */
.vendor_id = 0x0f0d, /* Hori Co., Ltd. */
.product_id = 0x00dc, /* HORIPAD S */
.version = 0x0112,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, FF */
.ev = { 0x0b, 0x00, 0x20 },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{
.name = "Switch Pro Controller via Bluetooth",
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x2009,
.version = 0x0001,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RX, RY, hat 0 */
.abs = { 0x1b, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 16 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE,
* BASE2..BASE6, unregistered event codes 0x12c-0x12e, DEAD */
/* 0x100 */ ZEROx4, 0xff, 0xff, 0x00, 0x00,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* TRIGGER_HAPPY1..TRIGGER_HAPPY2 */
/* 0x2c0 */ 0x03,
},
},
{
.name = "Switch Pro Controller via Bluetooth (Linux 6.2.11)",
.eviocgname = "Pro Controller",
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x2009,
.version = 0x0001,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RX, RY, hat 0 */
.abs = { 0x1b, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE, THUMBL, THUMBR,
* and an unassigned button code */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0xff,
},
},
{
.name = "Switch Pro Controller via USB",
.eviocgname = "Nintendo Co., Ltd. Pro Controller",
.usb_vendor_name = "Nintendo Co., Ltd.",
.usb_product_name = "Pro Controller",
.bus_type = 0x0003,
.vendor_id = 0x057e,
.product_id = 0x2009,
.version = 0x0111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, Z, RZ, HAT0X, HAT0Y */
.abs = { 0x27, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* 16 buttons: TRIGGER, THUMB, THUMB2, TOP, TOP2, PINKIE, BASE,
* BASE2..BASE6, unregistered event codes 0x12c-0x12e, DEAD */
/* 0x100 */ ZEROx4, 0xff, 0xff, 0x00, 0x00,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* TRIGGER_HAPPY1..TRIGGER_HAPPY2 */
/* 0x2c0 */ 0x03,
},
},
{ /* https://github.com/ValveSoftware/steam-devices/pull/40 */
.name = "PDP wired Pro Controller for Switch",
/* 0003:0e6f:0184 "Performance Designed Products" /
* "Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch" appears
* to be functionally equivalent */
.eviocgname = "PDP CO.,LTD. Faceoff Wired Pro Controller for Nintendo Switch",
.usb_vendor_name = "PDP CO.,LTD.",
.usb_product_name = "Faceoff Wired Pro Controller for Nintendo Switch",
.bus_type = 0x0003,
.vendor_id = 0x0e6f,
.product_id = 0x0180,
.version = 0x0111,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC */
.ev = { 0x1b },
/* X, Y, Z, RZ, HAT0X, HAT0Y */
.abs = { 0x27, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x3f,
},
},
{
.name = "NES Controller (R) NES-style Joycon from Nintendo Online",
.eviocgname = "NES Controller (R)",
/* Joy-Con (L), 0005:057e:2006 v0001, is functionally equivalent.
* Ordinary Joy-Con (R) and NES-style Joy-Con (L) are assumed to be
* functionally equivalent as well. */
.bus_type = 0x0005, /* Bluetooth-only */
.vendor_id = 0x057e,
.product_id = 0x2007,
.version = 0x0001,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RX, RY, hat 0 */
.abs = { 0x1b, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE, THUMBL, THUMBR,
* and an unassigned button code */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0xff,
},
},
{
.name = "Thrustmaster Racing Wheel FFB",
/* Several devices intended for PS4 are functionally equivalent to this:
* https://github.com/ValveSoftware/steam-devices/pull/34
* Mad Catz FightStick TE S+ PS4, 0003:0738:8384:0111 v0111
* (aka Street Fighter V Arcade FightStick TES+)
* Mad Catz FightStick TE2+ PS4, 0003:0738:8481 v0100
* (aka Street Fighter V Arcade FightStick TE2+)
* Bigben Interactive DAIJA Arcade Stick, 0003:146b:0d09 v0111
* (aka Nacon Daija PS4 Arcade Stick)
* Razer Razer Raiju Ultimate Wired, 0003:1532:1009 v0000
* Razer Razer Raiju Ultimate (Bluetooth), 0005:1532:1009 v0001
*/
.bus_type = 0x0003,
.vendor_id = 0x044f,
.product_id = 0xb66d,
.version = 0x0110,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.ev = { 0x0b },
/* XYZ, RXYZ, hat 0 */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x3f,
},
},
{
.name = "Thrustmaster T.Flight Hotas X",
.bus_type = 0x0003,
.vendor_id = 0x044f,
.product_id = 0xb108,
.version = 0x0100,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.ev = { 0x0b },
/* XYZ, RZ, throttle, hat 0 */
.abs = { 0x67, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* trigger, thumb, thumb2, top, top2, pinkie, base,
* base2..base6 */
/* 0x100 */ ZEROx4, 0xff, 0x0f
},
},
{
.name = "8BitDo N30 Pro via Bluetooth",
/* This device has also been seen reported with an additional
* unassigned button code, the same as the SNES30 v0100 via Bluetooth */
.bus_type = 0x0005,
.vendor_id = 0x2dc8,
.product_id = 0x3820,
.version = 0x0100,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS, MSC */
.ev = { 0x1b },
/* XYZ, RZ, gas, brake, hat0 */
.abs = { 0x27, 0x06, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, select, start, mode, thumbl,
* thumbr */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x7f,
},
},
{
.name = "8BitDo N30 Pro 2 v0111",
.bus_type = 0x0003,
.vendor_id = 0x2dc8,
.product_id = 0x9015,
.version = 0x0111,
/* 8BitDo NES30 Pro via USB, 0003:2dc8:9001 v0111, is the same;
* but the same physical device via Bluetooth, 0005:2dc8:3820 v0100,
* matches 8BitDo SNES30 v0100 via Bluetooth instead (see above). */
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.ev = { 0x0b },
/* XYZ, RZ, gas, brake, hat0 */
.abs = { 0x27, 0x06, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, select, start, mode, thumbl,
* thumbr */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x7f,
},
},
{
.name = "8BitDo N30 Pro 2 via Bluetooth",
/* Physically the same device as the one that mimics an Xbox 360
* USB controller when wired */
.bus_type = 0x0005,
.vendor_id = 0x045e,
.product_id = 0x02e0,
.version = 0x0903,
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY, ABS, MSC, FF */
.ev = { 0x1b, 0x00, 0x20 },
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx8,
/* KEY_MENU */
/* 0x80 */ 0x00, 0x08, 0x00, 0x00, ZEROx4,
/* 0xc0 */ ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2 */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x03,
},
},
{
.name = "Retro Power SNES-style controller, 0003:0079:0011 v0110",
.bus_type = 0x0003,
.vendor_id = 0x0079,
.product_id = 0x0011,
.version = 0x0110,
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.ev = { 0x0b },
/* X, Y */
.abs = { 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* trigger, thumb, thumb2, top, top2, pinkie, base,
* base2..base4 */
/* 0x100 */ ZEROx4, 0xff, 0x03, 0x00, 0x00,
},
},
{
.name = "Google Stadia Controller rev.A",
.eviocgname = "Google LLC Stadia Controller rev. A",
.usb_vendor_name = "Google LLC",
.usb_product_name = "Stadia Controller rev. A",
/* This data is with USB-C, but the same physical device via Bluetooth,
* 0005:18d1:9400 v0000, is functionally equivalent other than having
* EVIOCGNAME = StadiaXXXX-YYYY where XXXX is the last 4 digits of
* the serial number and YYYY is some other mystery number */
.bus_type = 0x0003,
.vendor_id = 0x18d1,
.product_id = 0x9400,
.version = 0x0100,
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
.ev = { 0x0b },
/* XYZ, RZ, gas, brake, hat0 */
.abs = { 0x27, 0x06, 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* Volume up/down */
/* 0x40 */ ZEROx4, 0x00, 0x00, 0x0c, 0x00,
/* Media play/pause */
/* 0x80 */ ZEROx4, 0x10, 0x00, 0x00, 0x00,
/* 0xc0 */ ZEROx8,
/* ABXY, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
/* 0x280 */ ZEROx8,
/* TRIGGER_HAPPY 1-4 */
/* 0x2c0 */ 0x0f, 0x00, 0x00, 0x00, ZEROx4,
},
},
{
.name = "Microsoft Xbox Series S|X Controller (model 1914) via USB",
.eviocgname = "Microsoft Xbox Series S|X Controller",
.usb_vendor_name = "Microsoft",
.usb_product_name = "Controller",
/* Physically the same device as 0003:045e:0b13 v0515 below,
* but some functionality is mapped differently */
.bus_type = 0x0003,
.vendor_id = 0x045e,
.product_id = 0x0b12,
.version = 0x050f,
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
.ev = { 0x0b },
/* X, Y, Z, RX, RY, RZ, hat 0 */
.abs = { 0x3f, 0x00, 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx8,
/* Record */
/* 0x80 */ ZEROx4, 0x80, 0x00, 0x00, 0x00,
/* 0xc0 */ ZEROx8,
/* ABXY, TL, TR, SELECT, START, MODE, THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
},
},
{
.name = "Microsoft Xbox Series S|X Controller (model 1914) via Bluetooth",
.eviocgname = "Xbox Wireless Controller",
/* Physically the same device as 0003:045e:0b12 v050f above,
* but some functionality is mapped differently */
.bus_type = 0x0005,
.vendor_id = 0x045e,
.product_id = 0x0b13,
.version = 0x0515,
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
.ev = { 0x0b },
/* XYZ, RZ, gas, brake, hat0 */
.abs = { 0x27, 0x06, 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx8,
/* Record */
/* 0x80 */ ZEROx4, 0x80, 0x00, 0x00, 0x00,
/* 0xc0 */ ZEROx8,
/* ABC, XYZ, TL, TR, TL2, TR2, select, start, mode, thumbl,
* thumbr */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xff, 0x7f,
},
},
{
.name = "Wiimote - buttons",
.eviocgname = "Nintendo Wii Remote",
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x0306,
.version = 0x0600,
/* This one is a bit weird because some of the buttons are mapped
* to the arrow, page up and page down keys, so it's a joystick
* with a subset of a keyboard attached. */
/* TODO: Should this be JOYSTICK, or even JOYSTICK|HAS_KEYS? */
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY, FF */
.ev = { 0x03, 0x00, 0x20 },
.keys = {
/* 0x00 */ ZEROx8,
/* left, right, up down */
/* 0x40 */ ZEROx4, 0x80, 0x16, 0x00, 0x00,
/* 0x80 */ ZEROx8,
/* 0xc0 */ ZEROx8,
/* BTN_1, BTN_2, BTN_A, BTN_B, BTN_MODE */
/* 0x100 */ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10,
/* 0x140 */ ZEROx8,
/* next (keyboard page down), previous (keyboard page up) */
/* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4,
},
},
{
.name = "Wiimote - accelerometer",
.eviocgname = "Nintendo Wii Remote Accelerometer",
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x0306,
.version = 0x0600,
.expected = SDL_UDEV_DEVICE_ACCELEROMETER,
/* SYN, ABS */
.ev = { 0x09 },
/* RX, RY, RZ - even though it would more conventionally be X, Y, Z */
.abs = { 0x38 },
},
{
.name = "Wiimote - Motion Plus gyroscope",
.eviocgname = "Nintendo Wii Remote Motion Plus",
/* Note that if we only look at the bus type, vendor, product, version
* and axes, this is indistinguishable from the accelerometer */
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x0306,
.version = 0x0600,
.expected = SDL_UDEV_DEVICE_ACCELEROMETER,
/* SYN, ABS */
.ev = { 0x09 },
/* RX, RY, RZ */
.abs = { 0x38 },
},
{
.name = "Wiimote - IR positioning",
.eviocgname = "Nintendo Wii Remote IR",
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x0306,
.version = 0x0600,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SYN, ABS */
.ev = { 0x09 },
/* HAT0X, Y to HAT3X, Y */
.abs = { 0x00, 0x00, 0xff },
},
{
.name = "Wiimote - Nunchuck",
.eviocgname = "Nintendo Wii Remote Nunchuk",
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x0306,
.version = 0x0600,
/* TODO: Should this be JOYSTICK? It has one stick and two buttons */
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* RX, RY, RZ, hat 0 - even though this is an accelerometer, which
* would more conventionally be X, Y, Z, and a left joystick, which
* would more conventionally be X, Y */
.abs = { 0x38, 0x00, 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* C and Z buttons */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0x24, 0x00,
},
},
{
.name = "Wiimote - Classic Controller",
.eviocgname = "Nintendo Wii Remote Classic Controller",
.bus_type = 0x0005,
.vendor_id = 0x057e,
.product_id = 0x0306,
.version = 0x0600,
/* TODO: Should this be JOYSTICK, or maybe JOYSTICK|HAS_KEYS?
* It's unusual in the same ways as the Wiimote */
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* Hat 1-3 X and Y */
.abs = { 0x00, 0x00, 0xfc },
.keys = {
/* 0x00 */ ZEROx8,
/* left, right, up down */
/* 0x40 */ ZEROx4, 0x80, 0x16, 0x00, 0x00,
/* 0x80 */ ZEROx8,
/* 0xc0 */ ZEROx8,
/* A, B, X, Y, MODE, TL, TL2, TR, TR2 */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x13,
/* 0x140 */ ZEROx8,
/* next (keyboard page down), previous (keyboard page up) */
/* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4,
},
},
{
/* Flags guessed from kernel source code, not confirmed with real
* hardware */
.name = "Wiimote - Balance Board",
/* TODO: Should this be JOYSTICK? */
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* Hat 0-1 */
.abs = { 0x00, 0x00, 0x0f },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* BTN_A */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0x01, 0x00,
},
},
{
/* Flags guessed from kernel source code, not confirmed with real
* hardware */
.name = "Wiimote - Wii U Pro Controller",
.expected = SDL_UDEV_DEVICE_JOYSTICK,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, RX, RY */
.abs = { 0x1b },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* A, B, X, Y, TL, TR, TL2, TR2, SELECT, START, MODE,
* THUMBL, THUMBR */
/* 0x100 */ ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
/* 0x140 */ ZEROx8,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ ZEROx8,
/* Digital dpad */
/* 0x200 */ ZEROx4, 0x0f, 0x00, 0x00, 0x00,
},
},
{
.name = "Synaptics TM3381-002 (Thinkpad X280 trackpad)",
.eviocgname = "Synaptics TM3381-002",
.bus_type = 0x001d, /* BUS_RMI */
.vendor_id = 0x06cb,
.product_id = 0x0000,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_TOUCHPAD,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, pressure, multitouch */
.abs = { 0x03, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x06 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* Left mouse button */
/* 0x100 */ 0x00, 0x00, 0x01, 0x00, ZEROx4,
/* BTN_TOOL_FINGER and some multitouch gestures */
/* 0x140 */ 0x20, 0xe5
},
/* POINTER, BUTTONPAD */
.props = { 0x05 },
},
{
.name = "DELL08AF:00 (Dell XPS laptop touchpad)",
.bus_type = 0x18,
.vendor_id = 0x6cb,
.product_id = 0x76af,
.version = 0x100,
.ev = { 0x0b },
.expected = SDL_UDEV_DEVICE_TOUCHPAD,
/* X, Y, multitouch */
.abs = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x02 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* Left mouse button */
/* 0x100 */ 0x00, 0x00, 0x01, 0x00, ZEROx4,
/* BTN_TOOL_FINGER and some multitouch gestures */
/* 0x140 */ 0x20, 0xe5
},
/* POINTER, BUTTONPAD */
.props = { 0x05 },
},
{
.name = "TPPS/2 Elan TrackPoint (Thinkpad X280)",
.eviocgname = "TPPS/2 Elan TrackPoint",
.bus_type = 0x0011, /* BUS_I8042 */
.vendor_id = 0x0002,
.product_id = 0x000a,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_MOUSE,
/* SYN, KEY, REL */
.ev = { 0x07 },
/* X, Y */
.rel = { 0x03 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* Left, middle, right mouse buttons */
/* 0x100 */ 0x00, 0x00, 0x07,
},
/* POINTER, POINTING_STICK */
.props = { 0x21 },
},
{
.name = "Thinkpad ACPI buttons",
.eviocgname = "ThinkPad Extra Buttons",
.bus_type = 0x0019,
.vendor_id = 0x17aa,
.product_id = 0x5054,
.version = 0x4101,
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY, MSC, SW */
.ev = { 0x33 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx4, 0x00, 0x00, 0x0e, 0x01,
/* 0x80 */ 0x00, 0x50, 0x11, 0x51, 0x00, 0x28, 0x00, 0xc0,
/* 0xc0 */ 0x04, 0x20, 0x10, 0x02, 0x1b, 0x70, 0x01, 0x00,
/* 0x100 */ ZEROx8,
/* 0x140 */ ZEROx4, 0x00, 0x00, 0x50, 0x00,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ 0x00, 0x00, 0x04, 0x18, ZEROx4,
/* 0x200 */ ZEROx8,
/* 0x240 */ 0x40, 0x00, 0x01, 0x00, ZEROx4,
},
},
{
.name = "Thinkpad ACPI buttons (Linux 6.1)",
.eviocgname = "ThinkPad Extra Buttons",
.bus_type = 0x0019,
.vendor_id = 0x17aa,
.product_id = 0x5054,
.version = 0x4101,
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY, MSC, SW */
.ev = { 0x33 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx4, 0x00, 0x00, 0x0e, 0x01,
/* 0x80 */ 0x00, 0x50, 0x11, 0x51, 0x00, 0x28, 0x00, 0xc0,
/* 0xc0 */ 0x04, 0x20, 0x10, 0x02, 0x1b, 0x70, 0x01, 0x00,
/* 0x100 */ ZEROx8,
/* 0x140 */ ZEROx4, 0x00, 0x00, 0x50, 0x00,
/* 0x180 */ ZEROx4, 0x00, 0x00, 0x00, 0x70,
/* 0x1c0 */ 0x00, 0x00, 0x04, 0x18, 0x20, 0x00, 0x00, 0x00,
/* 0x200 */ ZEROx8,
/* 0x240 */ ZEROx8,
},
},
{
.name = "PC speaker",
.eviocgname = "PC Speaker",
.bus_type = 0x0010, /* BUS_ISA */
.vendor_id = 0x001f,
.product_id = 0x0001,
.version = 0x0100,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SYN, SND */
.ev = { 0x01, 0x00, 0x04 },
},
{
.name = "HDA Digital PCBeep",
.eviocgname = "HDA Digital PCBeep",
.bus_type = 0x0001,
.vendor_id = 0x10ec,
.product_id = 0x0257,
.version = 0x0001,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SYN, SND */
.ev = { 0x01, 0x00, 0x04 },
},
{
.name = "ALSA headphone detection, etc.",
.eviocgname = "HDA Intel PCH Mic",
/* HDA Intel PCH Headphone is functionally equivalent */
/* HDA Intel PCH HDMI/DP,pcm=3 is functionally equivalent */
/* HDA Intel PCH HDMI/DP,pcm=7 is functionally equivalent */
/* HDA Intel PCH HDMI/DP,pcm=8 is functionally equivalent */
.bus_type = 0x0000,
.vendor_id = 0x0000,
.product_id = 0x0000,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SYN, SW */
.ev = { 0x21 },
},
{
/* Assumed to be a reasonably typical i8042 (PC AT) keyboard */
.name = "Thinkpad T520 and X280 keyboards",
/* Steam Deck LCD/OLED keyboard interface is version 0xab83 but
* otherwise equivalent */
.eviocgname = "AT Translated Set 2 keyboard",
.bus_type = 0x0011, /* BUS_I8042 */
.vendor_id = 0x0001,
.product_id = 0x0001,
.version = 0xab54,
.expected = SDL_UDEV_DEVICE_HAS_KEYS | SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY, MSC, LED, REP */
.ev = { 0x13, 0x00, 0x12 },
.keys = {
/* 0x00 */ 0xfe, 0xff, 0xff, 0xff, FFx4,
/* 0x40 */ 0xff, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xff, 0xfe,
/* 0x80 */ 0x01, 0xd0, 0x00, 0xf8, 0x78, 0x30, 0x80, 0x03,
/* 0xc0 */ 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00,
},
},
{
.name = "Thinkpad X280 sleep button",
.eviocgname = "Sleep Button",
.bus_type = 0x0019, /* BUS_HOST */
.vendor_id = 0x0000,
.product_id = 0x0003,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx8,
/* KEY_SLEEP */
/* 0x80 */ 0x00, 0x40,
},
},
{
/* As seen on Thinkpad X280, Steam Deck LCD, Steam Deck OLED */
.name = "ACPI lid switch",
.eviocgname = "Lid Switch",
.bus_type = 0x0019, /* BUS_HOST */
.vendor_id = 0x0000,
.product_id = 0x0005,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SYN, SW */
.ev = { 0x21 },
},
{
/* As seen on Thinkpad X280, Steam Deck LCD, Steam Deck OLED */
.name = "ACPI power button",
.eviocgname = "Power Button",
.bus_type = 0x0019, /* BUS_HOST */
.vendor_id = 0x0000,
.product_id = 0x0001,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* KEY_POWER */
/* 0x40 */ ZEROx4, 0x00, 0x00, 0x10, 0x00,
},
},
{
/* As seen on Thinkpad X280, Steam Deck LCD, Steam Deck OLED */
.name = "ACPI video bus",
.eviocgname = "Video Bus",
.bus_type = 0x0019, /* BUS_HOST */
.vendor_id = 0x0000,
.product_id = 0x0006,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx8,
/* 0x80 */ ZEROx8,
/* brightness control, video mode, display off */
/* 0xc0 */ ZEROx4, 0x0b, 0x00, 0x3e, 0x00,
},
},
{
.name = "Thinkpad X280 webcam",
.eviocgname = "Integrated Camera: Integrated C",
.usb_vendor_name = "Chicony Electronics Co.,Ltd.",
.usb_product_name = "Integrated Camera",
.bus_type = 0x0003,
.vendor_id = 0x04f2,
.product_id = 0xb604,
.version = 0x0027,
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx8,
/* 0x80 */ ZEROx8,
/* KEY_CAMERA */
/* 0xc0 */ 0x00, 0x00, 0x10, 0x00, ZEROx4,
},
},
{
.name = "Thinkpad X280 extra buttons",
.bus_type = 0x0019, /* BUS_HOST */
.vendor_id = 0x17aa,
.product_id = 0x5054,
.version = 0x4101,
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx4, 0x00, 0x00, 0x0e, 0x01,
/* 0x80 */ 0x00, 0x50, 0x11, 0x51, 0x00, 0x28, 0x00, 0xc0,
/* 0xc0 */ 0x04, 0x20, 0x10, 0x02, 0x1b, 0x70, 0x01, 0x00,
/* 0x100 */ ZEROx8,
/* 0x140 */ ZEROx4, 0x00, 0x00, 0x50, 0x00,
/* 0x180 */ ZEROx8,
/* 0x1c0 */ 0x00, 0x00, 0x04, 0x18, ZEROx4,
/* 0x200 */ ZEROx8,
/* 0x240 */ 0x40, 0x00, 0x01, 0x00, ZEROx4,
},
},
{
.name = "Thinkpad USB keyboard with Trackpoint - keyboard",
.eviocgname = "Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint",
.usb_vendor_name = "Lite-On Technology Corp.",
.usb_product_name = "ThinkPad USB Keyboard with TrackPoint",
.bus_type = 0x0003,
.vendor_id = 0x17ef,
.product_id = 0x6009,
.expected = SDL_UDEV_DEVICE_HAS_KEYS | SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY, MSC, LED, REP */
.ev = { 0x13, 0x00, 0x12 },
.keys = {
/* 0x00 */ 0xfe, 0xff, 0xff, 0xff, FFx4,
/* 0x40 */ 0xff, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xbe, 0xfe,
/* 0x80 */ 0xff, 0x57, 0x40, 0xc1, 0x7a, 0x20, 0x9f, 0xff,
/* 0xc0 */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
},
.hid_report_descriptor_length = sizeof (thinkpad_usb_keyboard_hid_report_descriptor),
.hid_report_descriptor = &thinkpad_usb_keyboard_hid_report_descriptor[0],
},
{
.name = "Thinkpad USB keyboard with Trackpoint - Trackpoint",
.eviocgname = "Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint",
.usb_vendor_name = "Lite-On Technology Corp.",
.usb_product_name = "ThinkPad USB Keyboard with TrackPoint",
.bus_type = 0x0003,
.vendor_id = 0x17ef,
.product_id = 0x6009,
.version = 0x0110,
/* For some reason the special keys like mute and wlan toggle
* show up here instead of, or in addition to, as part of
* the keyboard - so both udev and SDL report this as having keys too. */
.expected = SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_HAS_KEYS,
/* SYN, KEY, REL, MSC, LED */
.ev = { 0x17, 0x00, 0x02 },
/* X, Y */
.rel = { 0x03 },
.keys = {
/* 0x00 */ ZEROx8,
/* 0x40 */ ZEROx4, 0x00, 0x00, 0x1e, 0x00,
/* 0x80 */ 0x00, 0xcc, 0x11, 0x01, 0x78, 0x40, 0x00, 0xc0,
/* 0xc0 */ 0x00, 0x20, 0x10, 0x00, 0x0b, 0x50, 0x00, 0x00,
/* Mouse buttons: left, right, middle, "task" */
/* 0x100 */ 0x00, 0x00, 0x87, 0x68, ZEROx4,
/* 0x140 */ ZEROx4, 0x00, 0x00, 0x10, 0x00,
/* 0x180 */ ZEROx4, 0x00, 0x00, 0x40, 0x00,
},
.hid_report_descriptor_length = sizeof (thinkpad_usb_trackpoint_hid_report_descriptor),
.hid_report_descriptor = &thinkpad_usb_trackpoint_hid_report_descriptor[0],
},
{ /* https://github.com/ValveSoftware/Proton/issues/5126 */
.name = "Smarty Co. VRS DirectForce Pro Pedals",
.bus_type = 0x0003,
.vendor_id = 0x0483, /* STMicroelectronics */
.product_id = 0xa3be, /* VRS DirectForce Pro Pedals */
.version = 0x0111,
/* TODO: Ideally we would identify this as a joystick, but there
* isn't currently enough information to do that without a table
* of known devices. */
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.todo = "https://github.com/ValveSoftware/Proton/issues/5126",
/* SYN, ABS */
.ev = { 0x09 },
/* X, Y, Z */
.abs = { 0x07 },
.hid_report_descriptor_length = sizeof (vrs_pedals_hid_report_descriptor),
.hid_report_descriptor = &vrs_pedals_hid_report_descriptor[0],
},
{ /* https://github.com/ValveSoftware/Proton/issues/5126 */
.name = "Heusinkveld Heusinkveld Sim Pedals Ultimate",
.bus_type = 0x0003,
.vendor_id = 0x30b7, /* Heusinkveld Engineering */
.product_id = 0x1003, /* Heusinkveld Sim Pedals Ultimate */
.version = 0x0000,
/* TODO: Ideally we would identify this as a joystick, but there
* isn't currently enough information to do that without a table
* of known devices. */
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.todo = "https://github.com/ValveSoftware/Proton/issues/5126",
/* SYN, ABS */
.ev = { 0x09 },
/* RX, RY, RZ */
.abs = { 0x38 },
.hid_report_descriptor_length = sizeof (heusinkveld_pedals_hid_report_descriptor),
.hid_report_descriptor = &heusinkveld_pedals_hid_report_descriptor[0],
},
{ /* https://github.com/ValveSoftware/Proton/issues/5126 */
.name = "Vitaly [mega_mozg] Naidentsev ODDOR-handbrake",
.bus_type = 0x0003,
.vendor_id = 0x0000,
.product_id = 0x0000,
.version = 0x0001,
/* TODO: Ideally we would identify this as a joystick by it having
* the joystick-specific THROTTLE axis and TRIGGER/THUMB buttons */
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.todo = "https://github.com/ValveSoftware/Proton/issues/5126",
/* SYN, KEY, ABS, MSC */
.ev = { 0x1b },
/* THROTTLE only */
.abs = { 0x40 },
.keys = {
/* 0x00-0xff */ ZEROx8, ZEROx8, ZEROx8, ZEROx8,
/* TRIGGER = 0x120, THUMB = 0x121 */
/* 0x100 */ ZEROx4, 0x03, 0x00, 0x00, 0x00,
},
},
{ /* https://github.com/ValveSoftware/Proton/issues/5126 */
.name = "Leo Bodnar Logitech® G25 Pedals",
.bus_type = 0x0003,
.vendor_id = 0x1dd2, /* Leo Bodnar Electronics Ltd */
.product_id = 0x100c,
.version = 0x0110,
/* TODO: Ideally we would identify this as a joystick, but there
* isn't currently enough information to do that without a table
* of known devices. */
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.todo = "https://github.com/ValveSoftware/Proton/issues/5126",
/* SYN, ABS */
.ev = { 0x09 },
/* RX, RY, RZ */
.abs = { 0x38 },
},
{ /* https://github.com/ValveSoftware/Proton/issues/5126 */
.name = "FANATEC ClubSport USB Handbrake",
.bus_type = 0x0003,
.vendor_id = 0x0eb7,
.product_id = 0x1a93,
.version = 0x0111,
/* TODO: Ideally we would identify this as a joystick, but there
* isn't currently enough information to do that without a table
* of known devices. */
.expected = SDL_UDEV_DEVICE_JOYSTICK,
.todo = "https://github.com/ValveSoftware/Proton/issues/5126",
/* SYN, ABS */
.ev = { 0x09 },
/* X only */
.abs = { 0x01 },
.hid_report_descriptor_length = sizeof (fanatec_handbrake_hid_report_descriptor),
.hid_report_descriptor = &fanatec_handbrake_hid_report_descriptor[0],
},
{ /* Artificial test data, not a real device */
.name = "Fake accelerometer with fewer than usual axes reported",
.expected = SDL_UDEV_DEVICE_ACCELEROMETER,
/* SYN, ABS */
.ev = { 0x09 },
/* X only */
.abs = { 0x01 },
/* ACCELEROMETER */
.props = { 0x40 },
},
{ /* Artificial test data, not a real device */
.name = "Fake pointing stick with no buttons",
.expected = SDL_UDEV_DEVICE_MOUSE,
/* SYN, REL */
.ev = { 0x05 },
/* X,Y */
.rel = { 0x03 },
/* POINTER, POINTING_STICK */
.props = { 0x21 },
},
{ /* Artificial test data, not a real device */
.name = "Fake buttonpad",
.expected = SDL_UDEV_DEVICE_TOUCHPAD,
/* SYN, ABS */
.ev = { 0x09 },
/* X,Y */
.abs = { 0x03 },
/* POINTER, BUTTONPAD */
.props = { 0x05 },
},
{
.name = "No information",
.expected = SDL_UDEV_DEVICE_UNKNOWN,
}
};
/* *INDENT-ON* */ /* clang-format on */
/* The Linux kernel provides capability info in EVIOCGBIT and in /sys
* as an array of unsigned long in native byte order, rather than an array
* of bytes, an array of native-endian 32-bit words or an array of
* native-endian 64-bit words like you might have reasonably expected.
* The order of words in the array is always lowest-valued first: for
* instance, the first unsigned long in abs[] contains the bit representing
* absolute axis 0 (ABS_X).
*
* The constant arrays above provide test data in little-endian, because
* that's the easiest representation for hard-coding into a test like this.
* On a big-endian platform we need to byteswap it, one unsigned long at a
* time, to match what the kernel would produce. This requires us to choose
* an appropriate byteswapping function for the architecture's word size. */
SDL_COMPILE_TIME_ASSERT(sizeof_long, sizeof(unsigned long) == 4 || sizeof(unsigned long) == 8);
#define SwapLongLE(X) \
((sizeof(unsigned long) == 4) ? SDL_Swap32LE(X) : SDL_Swap64LE(X))
static int
run_test(void)
{
int success = 1;
size_t i;
for (i = 0; i < SDL_arraysize(guess_tests); i++) {
const GuessTest *t = &guess_tests[i];
size_t j;
int actual;
struct
{
unsigned long props[NBITS(INPUT_PROP_MAX)];
unsigned long ev[NBITS(EV_MAX)];
unsigned long abs[NBITS(ABS_MAX)];
unsigned long keys[NBITS(KEY_MAX)];
unsigned long rel[NBITS(REL_MAX)];
2023-03-08 23:18:02 +03:00
} caps;
printf("%s...\n", t->name);
SDL_memset(&caps, '\0', sizeof(caps));
SDL_memcpy(caps.props, t->props, sizeof(t->props));
SDL_memcpy(caps.ev, t->ev, sizeof(t->ev));
SDL_memcpy(caps.keys, t->keys, sizeof(t->keys));
SDL_memcpy(caps.abs, t->abs, sizeof(t->abs));
SDL_memcpy(caps.rel, t->rel, sizeof(t->rel));
for (j = 0; j < SDL_arraysize(caps.props); j++) {
caps.props[j] = SwapLongLE(caps.props[j]);
}
for (j = 0; j < SDL_arraysize(caps.ev); j++) {
caps.ev[j] = SwapLongLE(caps.ev[j]);
}
for (j = 0; j < SDL_arraysize(caps.keys); j++) {
caps.keys[j] = SwapLongLE(caps.keys[j]);
}
for (j = 0; j < SDL_arraysize(caps.abs); j++) {
caps.abs[j] = SwapLongLE(caps.abs[j]);
}
for (j = 0; j < SDL_arraysize(caps.rel); j++) {
caps.rel[j] = SwapLongLE(caps.rel[j]);
}
actual = SDL_EVDEV_GuessDeviceClass(caps.props, caps.ev, caps.abs,
caps.keys, caps.rel);
if (actual == t->expected) {
printf("\tOK\n");
} else {
printf("\tExpected 0x%08x\n", t->expected);
for (j = 0; device_classes[j].code != 0; j++) {
if (t->expected & device_classes[j].code) {
printf("\t\t%s\n", device_classes[j].name);
}
}
printf("\tGot 0x%08x\n", actual);
for (j = 0; device_classes[j].code != 0; j++) {
if (actual & device_classes[j].code) {
printf("\t\t%s\n", device_classes[j].name);
}
}
if (t->todo) {
printf("\tKnown issue, ignoring: %s\n", t->todo);
} else {
printf("\tFailed\n");
success = 0;
}
}
}
return success;
}
#else /* !(HAVE_LIBUDEV_H || defined(SDL_JOYSTICK_LINUX)) */
static int
run_test(void)
{
printf("SDL compiled without evdev capability check.\n");
return 1;
}
#endif
int main(int argc, char *argv[])
{
int result;
SDLTest_CommonState *state;
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0);
2023-11-10 00:29:15 +03:00
if (!state) {
return 1;
}
/* Parse commandline */
if (!SDLTest_CommonDefaultArgs(state, argc, argv)) {
return 1;
}
result = run_test() ? 0 : 1;
SDL_Quit();
SDLTest_CommonDestroyState(state);
return result;
}