1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifndef SDL_JOYSTICK_HIDAPI_H
24#define SDL_JOYSTICK_HIDAPI_H
25
26#include "../usb_ids.h"
27
28// This is the full set of HIDAPI drivers available
29#define SDL_JOYSTICK_HIDAPI_GAMECUBE
30#define SDL_JOYSTICK_HIDAPI_LUNA
31#define SDL_JOYSTICK_HIDAPI_PS3
32#define SDL_JOYSTICK_HIDAPI_PS4
33#define SDL_JOYSTICK_HIDAPI_PS5
34#define SDL_JOYSTICK_HIDAPI_STADIA
35#define SDL_JOYSTICK_HIDAPI_STEAM
36#define SDL_JOYSTICK_HIDAPI_STEAMDECK
37#define SDL_JOYSTICK_HIDAPI_SWITCH
38#define SDL_JOYSTICK_HIDAPI_WII
39#define SDL_JOYSTICK_HIDAPI_XBOX360
40#define SDL_JOYSTICK_HIDAPI_XBOXONE
41#define SDL_JOYSTICK_HIDAPI_SHIELD
42#define SDL_JOYSTICK_HIDAPI_STEAM_HORI
43#define SDL_JOYSTICK_HIDAPI_LG4FF
44
45// Joystick capability definitions
46#define SDL_JOYSTICK_CAP_MONO_LED 0x00000001
47#define SDL_JOYSTICK_CAP_RGB_LED 0x00000002
48#define SDL_JOYSTICK_CAP_PLAYER_LED 0x00000004
49#define SDL_JOYSTICK_CAP_RUMBLE 0x00000010
50#define SDL_JOYSTICK_CAP_TRIGGER_RUMBLE 0x00000020
51
52// Whether HIDAPI is enabled by default
53#if defined(SDL_PLATFORM_ANDROID) || \
54 defined(SDL_PLATFORM_IOS) || \
55 defined(SDL_PLATFORM_TVOS) || \
56 defined(SDL_PLATFORM_VISIONOS)
57// On Android, HIDAPI prompts for permissions and acquires exclusive access to the device, and on Apple mobile platforms it doesn't do anything except for handling Bluetooth Steam Controllers, so we'll leave it off by default.
58#define SDL_HIDAPI_DEFAULT false
59#else
60#define SDL_HIDAPI_DEFAULT true
61#endif
62
63// The maximum size of a USB packet for HID devices
64#define USB_PACKET_LENGTH 64
65
66// Forward declaration
67struct SDL_HIDAPI_DeviceDriver;
68
69typedef struct SDL_HIDAPI_Device
70{
71 char *name;
72 char *manufacturer_string;
73 char *product_string;
74 char *path;
75 Uint16 vendor_id;
76 Uint16 product_id;
77 Uint16 version;
78 char *serial;
79 SDL_GUID guid;
80 int interface_number; // Available on Windows and Linux
81 int interface_class;
82 int interface_subclass;
83 int interface_protocol;
84 Uint16 usage_page; // Available on Windows and macOS
85 Uint16 usage; // Available on Windows and macOS
86 bool is_bluetooth;
87 SDL_JoystickType joystick_type;
88 SDL_GamepadType type;
89 int steam_virtual_gamepad_slot;
90
91 struct SDL_HIDAPI_DeviceDriver *driver;
92 void *context;
93 SDL_Mutex *dev_lock;
94 SDL_hid_device *dev;
95 SDL_AtomicInt rumble_pending;
96 int num_joysticks;
97 SDL_JoystickID *joysticks;
98
99 // Used during scanning for device changes
100 bool seen;
101
102 // Used to flag that the device is being updated
103 bool updating;
104
105 // Used to flag devices that failed open
106 // This can happen on Windows with Bluetooth devices that have turned off
107 bool broken;
108
109 struct SDL_HIDAPI_Device *parent;
110 int num_children;
111 struct SDL_HIDAPI_Device **children;
112
113 struct SDL_HIDAPI_Device *next;
114} SDL_HIDAPI_Device;
115
116typedef struct SDL_HIDAPI_DeviceDriver
117{
118 const char *name;
119 bool enabled;
120 void (*RegisterHints)(SDL_HintCallback callback, void *userdata);
121 void (*UnregisterHints)(SDL_HintCallback callback, void *userdata);
122 bool (*IsEnabled)(void);
123 bool (*IsSupportedDevice)(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol);
124 bool (*InitDevice)(SDL_HIDAPI_Device *device);
125 int (*GetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id);
126 void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index);
127 bool (*UpdateDevice)(SDL_HIDAPI_Device *device);
128 bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
129 bool (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
130 bool (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble);
131 Uint32 (*GetJoystickCapabilities)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
132 bool (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
133 bool (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size);
134 bool (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled);
135 void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
136 void (*FreeDevice)(SDL_HIDAPI_Device *device);
137
138} SDL_HIDAPI_DeviceDriver;
139
140// HIDAPI device support
141extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverCombined;
142extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube;
143extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverJoyCons;
144extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna;
145extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverNintendoClassic;
146extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS3;
147extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS3ThirdParty;
148extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS3SonySixaxis;
149extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4;
150extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5;
151extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverShield;
152extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia;
153extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam;
154extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamDeck;
155extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch;
156extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverWii;
157extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360;
158extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W;
159extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne;
160extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamHori;
161extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLg4ff;
162
163// Return true if a HID device is present and supported as a joystick of the given type
164extern bool HIDAPI_IsDeviceTypePresent(SDL_GamepadType type);
165
166// Return true if a HID device is present and supported as a joystick
167extern bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
168
169// Return the name of a connected device, which should be freed with SDL_free(), or NULL if it's not available
170extern char *HIDAPI_GetDeviceProductName(Uint16 vendor_id, Uint16 product_id);
171
172// Return the manufacturer of a connected device, which should be freed with SDL_free(), or NULL if it's not available
173extern char *HIDAPI_GetDeviceManufacturerName(Uint16 vendor_id, Uint16 product_id);
174
175// Return the type of a joystick if it's present and supported
176extern SDL_JoystickType HIDAPI_GetJoystickTypeFromGUID(SDL_GUID guid);
177
178// Return the type of a game controller if it's present and supported
179extern SDL_GamepadType HIDAPI_GetGamepadTypeFromGUID(SDL_GUID guid);
180
181extern void HIDAPI_UpdateDevices(void);
182extern void HIDAPI_SetDeviceName(SDL_HIDAPI_Device *device, const char *name);
183extern void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 vendor_id, Uint16 product_id);
184extern void HIDAPI_SetDeviceSerial(SDL_HIDAPI_Device *device, const char *serial);
185extern bool HIDAPI_HasConnectedUSBDevice(const char *serial);
186extern void HIDAPI_DisconnectBluetoothDevice(const char *serial);
187extern bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID);
188extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID);
189extern void HIDAPI_UpdateDeviceProperties(SDL_HIDAPI_Device *device);
190
191extern void HIDAPI_DumpPacket(const char *prefix, const Uint8 *data, int size);
192
193extern bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product);
194
195extern float HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max);
196
197#endif // SDL_JOYSTICK_HIDAPI_H
198