SDL_sysjoystick.c 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "SDL_internal.h"
  19. #ifdef SDL_JOYSTICK_LINUX
  20. #ifndef SDL_INPUT_LINUXEV
  21. #error SDL now requires a Linux 2.4+ kernel with /dev/input/event support.
  22. #endif
  23. // This is the Linux implementation of the SDL joystick API
  24. #include <sys/stat.h>
  25. #include <errno.h> // errno, strerror
  26. #include <fcntl.h>
  27. #include <limits.h> // For the definition of PATH_MAX
  28. #ifdef HAVE_INOTIFY
  29. #include <sys/inotify.h>
  30. #include <string.h> // strerror
  31. #endif
  32. #include <sys/ioctl.h>
  33. #include <unistd.h>
  34. #include <dirent.h>
  35. #include <linux/joystick.h>
  36. #include "../../events/SDL_events_c.h"
  37. #include "../../core/linux/SDL_evdev.h"
  38. #include "../SDL_sysjoystick.h"
  39. #include "../SDL_joystick_c.h"
  40. #include "../usb_ids.h"
  41. #include "SDL_sysjoystick_c.h"
  42. #include "../hidapi/SDL_hidapijoystick_c.h"
  43. // This isn't defined in older Linux kernel headers
  44. #ifndef MSC_TIMESTAMP
  45. #define MSC_TIMESTAMP 0x05
  46. #endif
  47. #ifndef SYN_DROPPED
  48. #define SYN_DROPPED 3
  49. #endif
  50. #ifndef BTN_NORTH
  51. #define BTN_NORTH 0x133
  52. #endif
  53. #ifndef BTN_WEST
  54. #define BTN_WEST 0x134
  55. #endif
  56. #ifndef BTN_DPAD_UP
  57. #define BTN_DPAD_UP 0x220
  58. #endif
  59. #ifndef BTN_DPAD_DOWN
  60. #define BTN_DPAD_DOWN 0x221
  61. #endif
  62. #ifndef BTN_DPAD_LEFT
  63. #define BTN_DPAD_LEFT 0x222
  64. #endif
  65. #ifndef BTN_DPAD_RIGHT
  66. #define BTN_DPAD_RIGHT 0x223
  67. #endif
  68. #ifndef BTN_GRIPL
  69. #define BTN_GRIPL 0x224
  70. #endif
  71. #ifndef BTN_GRIPR
  72. #define BTN_GRIPR 0x225
  73. #endif
  74. #ifndef BTN_GRIPL2
  75. #define BTN_GRIPL2 0x226
  76. #endif
  77. #ifndef BTN_GRIPR2
  78. #define BTN_GRIPR2 0x227
  79. #endif
  80. #ifndef BTN_TRIGGER_HAPPY
  81. #define BTN_TRIGGER_HAPPY 0x2c0
  82. #define BTN_TRIGGER_HAPPY1 0x2c0
  83. #define BTN_TRIGGER_HAPPY2 0x2c1
  84. #define BTN_TRIGGER_HAPPY3 0x2c2
  85. #define BTN_TRIGGER_HAPPY4 0x2c3
  86. #define BTN_TRIGGER_HAPPY5 0x2c4
  87. #define BTN_TRIGGER_HAPPY6 0x2c5
  88. #define BTN_TRIGGER_HAPPY7 0x2c6
  89. #define BTN_TRIGGER_HAPPY8 0x2c7
  90. #define BTN_TRIGGER_HAPPY9 0x2c8
  91. #define BTN_TRIGGER_HAPPY10 0x2c9
  92. #define BTN_TRIGGER_HAPPY11 0x2ca
  93. #define BTN_TRIGGER_HAPPY12 0x2cb
  94. #define BTN_TRIGGER_HAPPY13 0x2cc
  95. #define BTN_TRIGGER_HAPPY14 0x2cd
  96. #define BTN_TRIGGER_HAPPY15 0x2ce
  97. #define BTN_TRIGGER_HAPPY16 0x2cf
  98. #define BTN_TRIGGER_HAPPY17 0x2d0
  99. #define BTN_TRIGGER_HAPPY18 0x2d1
  100. #define BTN_TRIGGER_HAPPY19 0x2d2
  101. #define BTN_TRIGGER_HAPPY20 0x2d3
  102. #define BTN_TRIGGER_HAPPY21 0x2d4
  103. #define BTN_TRIGGER_HAPPY22 0x2d5
  104. #define BTN_TRIGGER_HAPPY23 0x2d6
  105. #define BTN_TRIGGER_HAPPY24 0x2d7
  106. #define BTN_TRIGGER_HAPPY25 0x2d8
  107. #define BTN_TRIGGER_HAPPY26 0x2d9
  108. #define BTN_TRIGGER_HAPPY27 0x2da
  109. #define BTN_TRIGGER_HAPPY28 0x2db
  110. #define BTN_TRIGGER_HAPPY29 0x2dc
  111. #define BTN_TRIGGER_HAPPY30 0x2dd
  112. #define BTN_TRIGGER_HAPPY31 0x2de
  113. #define BTN_TRIGGER_HAPPY32 0x2df
  114. #define BTN_TRIGGER_HAPPY33 0x2e0
  115. #define BTN_TRIGGER_HAPPY34 0x2e1
  116. #define BTN_TRIGGER_HAPPY35 0x2e2
  117. #define BTN_TRIGGER_HAPPY36 0x2e3
  118. #define BTN_TRIGGER_HAPPY37 0x2e4
  119. #define BTN_TRIGGER_HAPPY38 0x2e5
  120. #define BTN_TRIGGER_HAPPY39 0x2e6
  121. #define BTN_TRIGGER_HAPPY40 0x2e7
  122. #endif
  123. #include "../../core/linux/SDL_evdev_capabilities.h"
  124. #include "../../core/linux/SDL_udev.h"
  125. #if 0
  126. #define DEBUG_INPUT_EVENTS 1
  127. #endif
  128. #if 0
  129. #define DEBUG_GAMEPAD_MAPPING 1
  130. #endif
  131. typedef enum
  132. {
  133. ENUMERATION_UNSET,
  134. ENUMERATION_LIBUDEV,
  135. ENUMERATION_FALLBACK
  136. } EnumerationMethod;
  137. static EnumerationMethod enumeration_method = ENUMERATION_UNSET;
  138. static bool IsJoystickJSNode(const char *node);
  139. static void MaybeAddDevice(const char *path);
  140. static void MaybeRemoveDevice(const char *path);
  141. // A linked list of available joysticks
  142. typedef struct SDL_joylist_item
  143. {
  144. SDL_JoystickID device_instance;
  145. char *path; // "/dev/input/event2" or whatever
  146. char *name; // "SideWinder 3D Pro" or whatever
  147. char *driver; // "xpad" or whatever
  148. SDL_GUID guid;
  149. dev_t devnum;
  150. int steam_virtual_gamepad_slot;
  151. struct joystick_hwdata *hwdata;
  152. struct SDL_joylist_item *next;
  153. bool checked_mapping;
  154. SDL_GamepadMapping *mapping;
  155. } SDL_joylist_item;
  156. // A linked list of available gamepad sensors
  157. typedef struct SDL_sensorlist_item
  158. {
  159. char *path; // "/dev/input/event2" or whatever
  160. dev_t devnum;
  161. struct joystick_hwdata *hwdata;
  162. struct SDL_sensorlist_item *next;
  163. } SDL_sensorlist_item;
  164. static bool SDL_classic_joysticks = false;
  165. static SDL_joylist_item *SDL_joylist SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
  166. static SDL_joylist_item *SDL_joylist_tail SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
  167. static int numjoysticks SDL_GUARDED_BY(SDL_joystick_lock) = 0;
  168. static SDL_sensorlist_item *SDL_sensorlist SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
  169. static int inotify_fd = -1;
  170. static Uint64 last_joy_detect_time;
  171. static time_t last_input_dir_mtime;
  172. static void FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
  173. {
  174. if (inpid->vendor == 0x045e && inpid->product == 0x0b05 && inpid->version == 0x0903) {
  175. // This is a Microsoft Xbox One Elite Series 2 controller
  176. unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
  177. // The first version of the firmware duplicated all the inputs
  178. if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
  179. test_bit(0x2c0, keybit)) {
  180. // Change the version to 0x0902, so we can map it differently
  181. inpid->version = 0x0902;
  182. }
  183. }
  184. /* For Atari vcs modern and classic controllers have the version reflecting
  185. * firmware version, but the mapping stays stable so ignore
  186. * version information */
  187. if (inpid->vendor == 0x3250 && (inpid->product == 0x1001 || inpid->product == 0x1002)) {
  188. inpid->version = 0;
  189. }
  190. }
  191. #ifdef SDL_JOYSTICK_HIDAPI
  192. static bool IsVirtualJoystick(Uint16 vendor, Uint16 product, Uint16 version, const char *name)
  193. {
  194. if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_S && version == 0 &&
  195. SDL_strcmp(name, "Xbox One S Controller") == 0) {
  196. // This is the virtual device created by the xow driver
  197. return true;
  198. }
  199. return false;
  200. }
  201. #else
  202. static bool IsVirtualJoystick(Uint16 vendor, Uint16 product, Uint16 version, const char *name)
  203. {
  204. return false;
  205. }
  206. #endif // SDL_JOYSTICK_HIDAPI
  207. static bool GetSteamVirtualGamepadSlot(int fd, int *slot)
  208. {
  209. char name[128];
  210. if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) {
  211. const char *digits = SDL_strstr(name, "pad ");
  212. if (digits) {
  213. digits += 4;
  214. if (SDL_isdigit(*digits)) {
  215. *slot = SDL_atoi(digits);
  216. return true;
  217. }
  218. }
  219. }
  220. return false;
  221. }
  222. static int GuessDeviceClass(int fd)
  223. {
  224. unsigned long propbit[NBITS(INPUT_PROP_MAX)] = { 0 };
  225. unsigned long evbit[NBITS(EV_MAX)] = { 0 };
  226. unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
  227. unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
  228. unsigned long relbit[NBITS(REL_MAX)] = { 0 };
  229. if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
  230. (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
  231. (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) < 0) ||
  232. (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) {
  233. return 0;
  234. }
  235. /* This is a newer feature, so it's allowed to fail - if so, then the
  236. * device just doesn't have any properties. */
  237. (void) ioctl(fd, EVIOCGPROP(sizeof(propbit)), propbit);
  238. return SDL_EVDEV_GuessDeviceClass(propbit, evbit, absbit, keybit, relbit);
  239. }
  240. static bool GuessIsJoystick(int fd)
  241. {
  242. if (GuessDeviceClass(fd) & SDL_UDEV_DEVICE_JOYSTICK) {
  243. return true;
  244. }
  245. return false;
  246. }
  247. static bool GuessIsSensor(int fd)
  248. {
  249. if (GuessDeviceClass(fd) & SDL_UDEV_DEVICE_ACCELEROMETER) {
  250. return true;
  251. }
  252. return false;
  253. }
  254. static bool IsJoystick(const char *path, int *fd, char **name_return, Uint16 *vendor_return, Uint16 *product_return, SDL_GUID *guid, char **driver_return)
  255. {
  256. struct input_id inpid;
  257. char *name = NULL;
  258. char *driver = NULL;
  259. char product_string[128];
  260. int class = 0;
  261. SDL_zero(inpid);
  262. #ifdef SDL_USE_LIBUDEV
  263. // Opening input devices can generate synchronous device I/O, so avoid it if we can
  264. if (SDL_UDEV_GetProductInfo(path, &inpid, &class, &driver) &&
  265. !(class & SDL_UDEV_DEVICE_JOYSTICK)) {
  266. goto error;
  267. }
  268. #endif
  269. if (fd && *fd < 0) {
  270. *fd = open(path, O_RDONLY | O_CLOEXEC, 0);
  271. }
  272. if (!fd || *fd < 0) {
  273. goto error;
  274. }
  275. if (ioctl(*fd, JSIOCGNAME(sizeof(product_string)), product_string) <= 0) {
  276. // When udev enumeration or classification, we only got joysticks here, so no need to test
  277. if (enumeration_method != ENUMERATION_LIBUDEV && !class && !GuessIsJoystick(*fd)) {
  278. goto error;
  279. }
  280. // Could have vendor and product already from udev, but should agree with evdev
  281. if (ioctl(*fd, EVIOCGID, &inpid) < 0) {
  282. goto error;
  283. }
  284. if (ioctl(*fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) {
  285. goto error;
  286. }
  287. }
  288. name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string);
  289. if (!name) {
  290. goto error;
  291. }
  292. if (!IsVirtualJoystick(inpid.vendor, inpid.product, inpid.version, name) &&
  293. SDL_JoystickHandledByAnotherDriver(&SDL_LINUX_JoystickDriver, inpid.vendor, inpid.product, inpid.version, name)) {
  294. goto error;
  295. }
  296. FixupDeviceInfoForMapping(*fd, &inpid);
  297. #ifdef DEBUG_JOYSTICK
  298. SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
  299. #endif
  300. if (SDL_ShouldIgnoreJoystick(inpid.vendor, inpid.product, inpid.version, name)) {
  301. goto error;
  302. }
  303. *name_return = name;
  304. *driver_return = driver;
  305. *vendor_return = inpid.vendor;
  306. *product_return = inpid.product;
  307. *guid = SDL_CreateJoystickGUID(inpid.bustype, inpid.vendor, inpid.product, inpid.version, NULL, product_string, 0, 0);
  308. return true;
  309. error:
  310. SDL_free(driver);
  311. SDL_free(name);
  312. return false;
  313. }
  314. static bool IsSensor(const char *path, int *fd)
  315. {
  316. struct input_id inpid;
  317. int class = 0;
  318. SDL_zero(inpid);
  319. #ifdef SDL_USE_LIBUDEV
  320. // Opening input devices can generate synchronous device I/O, so avoid it if we can
  321. if (SDL_UDEV_GetProductInfo(path, &inpid, &class, NULL) &&
  322. !(class & SDL_UDEV_DEVICE_ACCELEROMETER)) {
  323. return false;
  324. }
  325. #endif
  326. if (fd && *fd < 0) {
  327. *fd = open(path, O_RDONLY | O_CLOEXEC, 0);
  328. }
  329. if (!fd || *fd < 0) {
  330. return false;
  331. }
  332. if (!class && !GuessIsSensor(*fd)) {
  333. return false;
  334. }
  335. if (ioctl(*fd, EVIOCGID, &inpid) < 0) {
  336. return false;
  337. }
  338. if (inpid.vendor == USB_VENDOR_NINTENDO && inpid.product == USB_PRODUCT_NINTENDO_WII_REMOTE) {
  339. // Wii extension controls
  340. // These may create 3 sensor devices but we only support reading from 1: ignore them
  341. return false;
  342. }
  343. return true;
  344. }
  345. #ifdef SDL_USE_LIBUDEV
  346. static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
  347. {
  348. if (!devpath) {
  349. return;
  350. }
  351. switch (udev_type) {
  352. case SDL_UDEV_DEVICEADDED:
  353. if (!(udev_class & (SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_ACCELEROMETER))) {
  354. return;
  355. }
  356. if (SDL_classic_joysticks) {
  357. if (!IsJoystickJSNode(devpath)) {
  358. return;
  359. }
  360. } else {
  361. if (IsJoystickJSNode(devpath)) {
  362. return;
  363. }
  364. }
  365. // Wait a bit for the hidraw udev node to initialize
  366. SDL_Delay(10);
  367. MaybeAddDevice(devpath);
  368. break;
  369. case SDL_UDEV_DEVICEREMOVED:
  370. MaybeRemoveDevice(devpath);
  371. break;
  372. default:
  373. break;
  374. }
  375. }
  376. #endif // SDL_USE_LIBUDEV
  377. static void FreeJoylistItem(SDL_joylist_item *item)
  378. {
  379. SDL_free(item->mapping);
  380. SDL_free(item->path);
  381. SDL_free(item->name);
  382. SDL_free(item->driver);
  383. SDL_free(item);
  384. }
  385. static void FreeSensorlistItem(SDL_sensorlist_item *item)
  386. {
  387. SDL_free(item->path);
  388. SDL_free(item);
  389. }
  390. static void MaybeAddDevice(const char *path)
  391. {
  392. struct stat sb;
  393. int fd = -1;
  394. char *name = NULL;
  395. char *driver = NULL;
  396. Uint16 vendor, product;
  397. SDL_GUID guid;
  398. SDL_joylist_item *item;
  399. SDL_sensorlist_item *item_sensor;
  400. if (!path) {
  401. return;
  402. }
  403. fd = open(path, O_RDONLY | O_CLOEXEC, 0);
  404. if (fd < 0) {
  405. return;
  406. }
  407. if (fstat(fd, &sb) == -1) {
  408. close(fd);
  409. return;
  410. }
  411. SDL_LockJoysticks();
  412. // Check to make sure it's not already in list.
  413. for (item = SDL_joylist; item; item = item->next) {
  414. if (sb.st_rdev == item->devnum) {
  415. goto done; // already have this one
  416. }
  417. }
  418. for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = item_sensor->next) {
  419. if (sb.st_rdev == item_sensor->devnum) {
  420. goto done; // already have this one
  421. }
  422. }
  423. #ifdef DEBUG_INPUT_EVENTS
  424. SDL_Log("Checking %s", path);
  425. #endif
  426. if (IsJoystick(path, &fd, &name, &vendor, &product, &guid, &driver)) {
  427. #ifdef DEBUG_INPUT_EVENTS
  428. SDL_Log("found joystick: %s", path);
  429. #endif
  430. item = (SDL_joylist_item *)SDL_calloc(1, sizeof(SDL_joylist_item));
  431. if (!item) {
  432. SDL_free(name);
  433. goto done;
  434. }
  435. item->devnum = sb.st_rdev;
  436. item->steam_virtual_gamepad_slot = -1;
  437. item->path = SDL_strdup(path);
  438. item->name = name;
  439. item->guid = guid;
  440. item->driver = driver;
  441. if (vendor == USB_VENDOR_VALVE &&
  442. product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) {
  443. GetSteamVirtualGamepadSlot(fd, &item->steam_virtual_gamepad_slot);
  444. }
  445. if ((!item->path) || (!item->name)) {
  446. FreeJoylistItem(item);
  447. goto done;
  448. }
  449. item->device_instance = SDL_GetNextObjectID();
  450. if (!SDL_joylist_tail) {
  451. SDL_joylist = SDL_joylist_tail = item;
  452. } else {
  453. SDL_joylist_tail->next = item;
  454. SDL_joylist_tail = item;
  455. }
  456. // Need to increment the joystick count before we post the event
  457. ++numjoysticks;
  458. SDL_PrivateJoystickAdded(item->device_instance);
  459. goto done;
  460. }
  461. if (IsSensor(path, &fd)) {
  462. #ifdef DEBUG_INPUT_EVENTS
  463. SDL_Log("found sensor: %s", path);
  464. #endif
  465. item_sensor = (SDL_sensorlist_item *)SDL_calloc(1, sizeof(SDL_sensorlist_item));
  466. if (!item_sensor) {
  467. goto done;
  468. }
  469. item_sensor->devnum = sb.st_rdev;
  470. item_sensor->path = SDL_strdup(path);
  471. if (!item_sensor->path) {
  472. FreeSensorlistItem(item_sensor);
  473. goto done;
  474. }
  475. item_sensor->next = SDL_sensorlist;
  476. SDL_sensorlist = item_sensor;
  477. goto done;
  478. }
  479. done:
  480. close(fd);
  481. SDL_UnlockJoysticks();
  482. }
  483. static void RemoveJoylistItem(SDL_joylist_item *item, SDL_joylist_item *prev)
  484. {
  485. SDL_AssertJoysticksLocked();
  486. if (item->hwdata) {
  487. item->hwdata->item = NULL;
  488. }
  489. if (prev) {
  490. prev->next = item->next;
  491. } else {
  492. SDL_assert(SDL_joylist == item);
  493. SDL_joylist = item->next;
  494. }
  495. if (item == SDL_joylist_tail) {
  496. SDL_joylist_tail = prev;
  497. }
  498. // Need to decrement the joystick count before we post the event
  499. --numjoysticks;
  500. SDL_PrivateJoystickRemoved(item->device_instance);
  501. FreeJoylistItem(item);
  502. }
  503. static void RemoveSensorlistItem(SDL_sensorlist_item *item, SDL_sensorlist_item *prev)
  504. {
  505. SDL_AssertJoysticksLocked();
  506. if (item->hwdata) {
  507. item->hwdata->item_sensor = NULL;
  508. }
  509. if (prev) {
  510. prev->next = item->next;
  511. } else {
  512. SDL_assert(SDL_sensorlist == item);
  513. SDL_sensorlist = item->next;
  514. }
  515. /* Do not call SDL_PrivateJoystickRemoved here as RemoveJoylistItem will do it,
  516. * assuming both sensor and joy item are removed at the same time */
  517. FreeSensorlistItem(item);
  518. }
  519. static void MaybeRemoveDevice(const char *path)
  520. {
  521. SDL_joylist_item *item;
  522. SDL_joylist_item *prev = NULL;
  523. SDL_sensorlist_item *item_sensor;
  524. SDL_sensorlist_item *prev_sensor = NULL;
  525. if (!path) {
  526. return;
  527. }
  528. SDL_LockJoysticks();
  529. for (item = SDL_joylist; item; item = item->next) {
  530. // found it, remove it.
  531. if (SDL_strcmp(path, item->path) == 0) {
  532. RemoveJoylistItem(item, prev);
  533. goto done;
  534. }
  535. prev = item;
  536. }
  537. for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = item_sensor->next) {
  538. // found it, remove it.
  539. if (SDL_strcmp(path, item_sensor->path) == 0) {
  540. RemoveSensorlistItem(item_sensor, prev_sensor);
  541. goto done;
  542. }
  543. prev_sensor = item_sensor;
  544. }
  545. done:
  546. SDL_UnlockJoysticks();
  547. }
  548. static void HandlePendingRemovals(void)
  549. {
  550. SDL_joylist_item *prev = NULL;
  551. SDL_joylist_item *item = NULL;
  552. SDL_sensorlist_item *prev_sensor = NULL;
  553. SDL_sensorlist_item *item_sensor = NULL;
  554. SDL_AssertJoysticksLocked();
  555. item = SDL_joylist;
  556. while (item) {
  557. if (item->hwdata && item->hwdata->gone) {
  558. RemoveJoylistItem(item, prev);
  559. if (prev) {
  560. item = prev->next;
  561. } else {
  562. item = SDL_joylist;
  563. }
  564. } else {
  565. prev = item;
  566. item = item->next;
  567. }
  568. }
  569. item_sensor = SDL_sensorlist;
  570. while (item_sensor) {
  571. if (item_sensor->hwdata && item_sensor->hwdata->sensor_gone) {
  572. RemoveSensorlistItem(item_sensor, prev_sensor);
  573. if (prev_sensor) {
  574. item_sensor = prev_sensor->next;
  575. } else {
  576. item_sensor = SDL_sensorlist;
  577. }
  578. } else {
  579. prev_sensor = item_sensor;
  580. item_sensor = item_sensor->next;
  581. }
  582. }
  583. }
  584. static bool StrIsInteger(const char *string)
  585. {
  586. const char *p;
  587. if (*string == '\0') {
  588. return false;
  589. }
  590. for (p = string; *p != '\0'; p++) {
  591. if (*p < '0' || *p > '9') {
  592. return false;
  593. }
  594. }
  595. return true;
  596. }
  597. static bool IsJoystickJSNode(const char *node)
  598. {
  599. const char *last_slash = SDL_strrchr(node, '/');
  600. if (last_slash) {
  601. node = last_slash + 1;
  602. }
  603. return SDL_startswith(node, "js") && StrIsInteger(node + 2);
  604. }
  605. static bool IsJoystickEventNode(const char *node)
  606. {
  607. const char *last_slash = SDL_strrchr(node, '/');
  608. if (last_slash) {
  609. node = last_slash + 1;
  610. }
  611. return SDL_startswith(node, "event") && StrIsInteger(node + 5);
  612. }
  613. static bool IsJoystickDeviceNode(const char *node)
  614. {
  615. if (SDL_classic_joysticks) {
  616. return IsJoystickJSNode(node);
  617. } else {
  618. return IsJoystickEventNode(node);
  619. }
  620. }
  621. #ifdef HAVE_INOTIFY
  622. #ifdef HAVE_INOTIFY_INIT1
  623. static int SDL_inotify_init1(void)
  624. {
  625. return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
  626. }
  627. #else
  628. static int SDL_inotify_init1(void)
  629. {
  630. int fd = inotify_init();
  631. if (fd < 0) {
  632. return -1;
  633. }
  634. fcntl(fd, F_SETFL, O_NONBLOCK);
  635. fcntl(fd, F_SETFD, FD_CLOEXEC);
  636. return fd;
  637. }
  638. #endif
  639. static void LINUX_InotifyJoystickDetect(void)
  640. {
  641. union
  642. {
  643. struct inotify_event event;
  644. char storage[4096];
  645. char enough_for_inotify[sizeof(struct inotify_event) + NAME_MAX + 1];
  646. } buf;
  647. ssize_t bytes;
  648. size_t remain = 0;
  649. size_t len;
  650. char path[PATH_MAX];
  651. bytes = read(inotify_fd, &buf, sizeof(buf));
  652. if (bytes > 0) {
  653. remain = (size_t)bytes;
  654. }
  655. while (remain > 0) {
  656. if (buf.event.len > 0) {
  657. if (IsJoystickDeviceNode(buf.event.name)) {
  658. (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", buf.event.name);
  659. if (buf.event.mask & (IN_CREATE | IN_MOVED_TO | IN_ATTRIB)) {
  660. MaybeAddDevice(path);
  661. } else if (buf.event.mask & (IN_DELETE | IN_MOVED_FROM)) {
  662. MaybeRemoveDevice(path);
  663. }
  664. }
  665. }
  666. len = sizeof(struct inotify_event) + buf.event.len;
  667. remain -= len;
  668. if (remain != 0) {
  669. SDL_memmove(&buf.storage[0], &buf.storage[len], remain);
  670. }
  671. }
  672. }
  673. #endif // HAVE_INOTIFY
  674. static int get_event_joystick_index(int event)
  675. {
  676. int joystick_index = -1;
  677. int i, count;
  678. struct dirent **entries = NULL;
  679. char path[PATH_MAX];
  680. (void)SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event);
  681. count = scandir(path, &entries, NULL, alphasort);
  682. for (i = 0; i < count; ++i) {
  683. if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) {
  684. joystick_index = SDL_atoi(entries[i]->d_name + 2);
  685. }
  686. free(entries[i]); // This should NOT be SDL_free()
  687. }
  688. free(entries); // This should NOT be SDL_free()
  689. return joystick_index;
  690. }
  691. /* Detect devices by reading /dev/input. In the inotify code path we
  692. * have to do this the first time, to detect devices that already existed
  693. * before we started; in the non-inotify code path we do this repeatedly
  694. * (polling). */
  695. static int filter_entries(const struct dirent *entry)
  696. {
  697. return IsJoystickDeviceNode(entry->d_name);
  698. }
  699. static int SDLCALL sort_entries(const void *_a, const void *_b)
  700. {
  701. const struct dirent **a = (const struct dirent **)_a;
  702. const struct dirent **b = (const struct dirent **)_b;
  703. int numA, numB;
  704. int offset;
  705. if (SDL_classic_joysticks) {
  706. offset = 2; // strlen("js")
  707. numA = SDL_atoi((*a)->d_name + offset);
  708. numB = SDL_atoi((*b)->d_name + offset);
  709. } else {
  710. offset = 5; // strlen("event")
  711. numA = SDL_atoi((*a)->d_name + offset);
  712. numB = SDL_atoi((*b)->d_name + offset);
  713. // See if we can get the joystick ordering
  714. {
  715. int jsA = get_event_joystick_index(numA);
  716. int jsB = get_event_joystick_index(numB);
  717. if (jsA >= 0 && jsB >= 0) {
  718. numA = jsA;
  719. numB = jsB;
  720. } else if (jsA >= 0) {
  721. return -1;
  722. } else if (jsB >= 0) {
  723. return 1;
  724. }
  725. }
  726. }
  727. return numA - numB;
  728. }
  729. typedef struct
  730. {
  731. char *path;
  732. int slot;
  733. } VirtualGamepadEntry;
  734. static int SDLCALL sort_virtual_gamepads(const void *_a, const void *_b)
  735. {
  736. const VirtualGamepadEntry *a = (const VirtualGamepadEntry *)_a;
  737. const VirtualGamepadEntry *b = (const VirtualGamepadEntry *)_b;
  738. return a->slot - b->slot;
  739. }
  740. static void LINUX_ScanSteamVirtualGamepads(void)
  741. {
  742. int i, count;
  743. int fd;
  744. struct dirent **entries = NULL;
  745. char path[PATH_MAX];
  746. struct input_id inpid;
  747. int num_virtual_gamepads = 0;
  748. int virtual_gamepad_slot;
  749. VirtualGamepadEntry *virtual_gamepads = NULL;
  750. #ifdef SDL_USE_LIBUDEV
  751. int class;
  752. #endif
  753. count = scandir("/dev/input", &entries, filter_entries, NULL);
  754. for (i = 0; i < count; ++i) {
  755. (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name);
  756. #ifdef SDL_USE_LIBUDEV
  757. // Opening input devices can generate synchronous device I/O, so avoid it if we can
  758. class = 0;
  759. SDL_zero(inpid);
  760. if (SDL_UDEV_GetProductInfo(path, &inpid, &class, NULL) &&
  761. (inpid.vendor != USB_VENDOR_VALVE || inpid.product != USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) {
  762. free(entries[i]); // This should NOT be SDL_free()
  763. continue;
  764. }
  765. #endif
  766. fd = open(path, O_RDONLY | O_CLOEXEC, 0);
  767. if (fd >= 0) {
  768. if (ioctl(fd, EVIOCGID, &inpid) == 0 &&
  769. inpid.vendor == USB_VENDOR_VALVE &&
  770. inpid.product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD &&
  771. GetSteamVirtualGamepadSlot(fd, &virtual_gamepad_slot)) {
  772. VirtualGamepadEntry *new_virtual_gamepads = (VirtualGamepadEntry *)SDL_realloc(virtual_gamepads, (num_virtual_gamepads + 1) * sizeof(*virtual_gamepads));
  773. if (new_virtual_gamepads) {
  774. VirtualGamepadEntry *entry = &new_virtual_gamepads[num_virtual_gamepads];
  775. entry->path = SDL_strdup(path);
  776. entry->slot = virtual_gamepad_slot;
  777. if (entry->path) {
  778. virtual_gamepads = new_virtual_gamepads;
  779. ++num_virtual_gamepads;
  780. } else {
  781. SDL_free(entry->path);
  782. SDL_free(new_virtual_gamepads);
  783. }
  784. }
  785. }
  786. close(fd);
  787. }
  788. free(entries[i]); // This should NOT be SDL_free()
  789. }
  790. free(entries); // This should NOT be SDL_free()
  791. if (num_virtual_gamepads > 1) {
  792. SDL_qsort(virtual_gamepads, num_virtual_gamepads, sizeof(*virtual_gamepads), sort_virtual_gamepads);
  793. }
  794. for (i = 0; i < num_virtual_gamepads; ++i) {
  795. MaybeAddDevice(virtual_gamepads[i].path);
  796. SDL_free(virtual_gamepads[i].path);
  797. }
  798. SDL_free(virtual_gamepads);
  799. }
  800. static void LINUX_ScanInputDevices(void)
  801. {
  802. int i, count;
  803. struct dirent **entries = NULL;
  804. char path[PATH_MAX];
  805. count = scandir("/dev/input", &entries, filter_entries, NULL);
  806. if (count > 1) {
  807. SDL_qsort(entries, count, sizeof(*entries), sort_entries);
  808. }
  809. for (i = 0; i < count; ++i) {
  810. (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name);
  811. MaybeAddDevice(path);
  812. free(entries[i]); // This should NOT be SDL_free()
  813. }
  814. free(entries); // This should NOT be SDL_free()
  815. }
  816. static void LINUX_FallbackJoystickDetect(void)
  817. {
  818. const Uint32 SDL_JOY_DETECT_INTERVAL_MS = 3000; // Update every 3 seconds
  819. Uint64 now = SDL_GetTicks();
  820. if (!last_joy_detect_time || now >= (last_joy_detect_time + SDL_JOY_DETECT_INTERVAL_MS)) {
  821. struct stat sb;
  822. // Opening input devices can generate synchronous device I/O, so avoid it if we can
  823. if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
  824. // Look for Steam virtual gamepads first, and sort by Steam controller slot
  825. LINUX_ScanSteamVirtualGamepads();
  826. LINUX_ScanInputDevices();
  827. last_input_dir_mtime = sb.st_mtime;
  828. }
  829. last_joy_detect_time = now;
  830. }
  831. }
  832. static void LINUX_JoystickDetect(void)
  833. {
  834. #ifdef SDL_USE_LIBUDEV
  835. if (enumeration_method == ENUMERATION_LIBUDEV) {
  836. // Polling will happen in the main event loop
  837. } else
  838. #endif
  839. #ifdef HAVE_INOTIFY
  840. if (inotify_fd >= 0 && last_joy_detect_time != 0) {
  841. LINUX_InotifyJoystickDetect();
  842. } else
  843. #endif
  844. {
  845. LINUX_FallbackJoystickDetect();
  846. }
  847. HandlePendingRemovals();
  848. }
  849. static bool LINUX_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
  850. {
  851. // We don't override any other drivers
  852. return false;
  853. }
  854. static bool LINUX_JoystickInit(void)
  855. {
  856. const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE);
  857. #ifdef SDL_USE_LIBUDEV
  858. bool udev_initialized = SDL_UDEV_Init();
  859. #endif
  860. SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_LINUX_CLASSIC, false);
  861. enumeration_method = ENUMERATION_UNSET;
  862. // First see if the user specified one or more joysticks to use
  863. if (devices) {
  864. char *envcopy, *envpath, *delim;
  865. envcopy = SDL_strdup(devices);
  866. envpath = envcopy;
  867. while (envpath) {
  868. delim = SDL_strchr(envpath, ':');
  869. if (delim) {
  870. *delim++ = '\0';
  871. }
  872. MaybeAddDevice(envpath);
  873. envpath = delim;
  874. }
  875. SDL_free(envcopy);
  876. }
  877. // Force immediate joystick detection if using fallback
  878. last_joy_detect_time = 0;
  879. last_input_dir_mtime = 0;
  880. // Manually scan first, since we sort by device number and udev doesn't
  881. LINUX_JoystickDetect();
  882. #ifdef SDL_USE_LIBUDEV
  883. if (enumeration_method == ENUMERATION_UNSET) {
  884. if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", false)) {
  885. SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
  886. "udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
  887. enumeration_method = ENUMERATION_FALLBACK;
  888. } else if (SDL_GetSandbox() != SDL_SANDBOX_NONE) {
  889. SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
  890. "Container detected, disabling udev integration");
  891. enumeration_method = ENUMERATION_FALLBACK;
  892. } else {
  893. SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
  894. "Using udev for joystick device discovery");
  895. enumeration_method = ENUMERATION_LIBUDEV;
  896. }
  897. }
  898. if (enumeration_method == ENUMERATION_LIBUDEV) {
  899. if (udev_initialized) {
  900. // Set up the udev callback
  901. if (!SDL_UDEV_AddCallback(joystick_udev_callback)) {
  902. SDL_UDEV_Quit();
  903. return SDL_SetError("Could not set up joystick <-> udev callback");
  904. }
  905. // Force a scan to build the initial device list
  906. SDL_UDEV_Scan();
  907. } else {
  908. SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
  909. "udev init failed, disabling udev integration");
  910. enumeration_method = ENUMERATION_FALLBACK;
  911. }
  912. } else {
  913. if (udev_initialized) {
  914. SDL_UDEV_Quit();
  915. }
  916. }
  917. #endif
  918. if (enumeration_method != ENUMERATION_LIBUDEV) {
  919. #ifdef HAVE_INOTIFY
  920. inotify_fd = SDL_inotify_init1();
  921. if (inotify_fd < 0) {
  922. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
  923. "Unable to initialize inotify, falling back to polling: %s",
  924. strerror(errno));
  925. } else {
  926. /* We need to watch for attribute changes in addition to
  927. * creation, because when a device is first created, it has
  928. * permissions that we can't read. When udev chmods it to
  929. * something that we maybe *can* read, we'll get an
  930. * IN_ATTRIB event to tell us. */
  931. if (inotify_add_watch(inotify_fd, "/dev/input",
  932. IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) {
  933. close(inotify_fd);
  934. inotify_fd = -1;
  935. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
  936. "Unable to add inotify watch, falling back to polling: %s",
  937. strerror(errno));
  938. }
  939. }
  940. #endif // HAVE_INOTIFY
  941. }
  942. return true;
  943. }
  944. static int LINUX_JoystickGetCount(void)
  945. {
  946. SDL_AssertJoysticksLocked();
  947. return numjoysticks;
  948. }
  949. static SDL_joylist_item *GetJoystickByDevIndex(int device_index)
  950. {
  951. SDL_joylist_item *item;
  952. SDL_AssertJoysticksLocked();
  953. if ((device_index < 0) || (device_index >= numjoysticks)) {
  954. return NULL;
  955. }
  956. item = SDL_joylist;
  957. while (device_index > 0) {
  958. SDL_assert(item != NULL);
  959. device_index--;
  960. item = item->next;
  961. }
  962. return item;
  963. }
  964. static const char *LINUX_JoystickGetDeviceName(int device_index)
  965. {
  966. return GetJoystickByDevIndex(device_index)->name;
  967. }
  968. static const char *LINUX_JoystickGetDevicePath(int device_index)
  969. {
  970. return GetJoystickByDevIndex(device_index)->path;
  971. }
  972. static int LINUX_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index)
  973. {
  974. return GetJoystickByDevIndex(device_index)->steam_virtual_gamepad_slot;
  975. }
  976. static int LINUX_JoystickGetDevicePlayerIndex(int device_index)
  977. {
  978. return -1;
  979. }
  980. static void LINUX_JoystickSetDevicePlayerIndex(int device_index, int player_index)
  981. {
  982. }
  983. static SDL_GUID LINUX_JoystickGetDeviceGUID(int device_index)
  984. {
  985. return GetJoystickByDevIndex(device_index)->guid;
  986. }
  987. // Function to perform the mapping from device index to the instance id for this index
  988. static SDL_JoystickID LINUX_JoystickGetDeviceInstanceID(int device_index)
  989. {
  990. return GetJoystickByDevIndex(device_index)->device_instance;
  991. }
  992. static bool allocate_balldata(SDL_Joystick *joystick)
  993. {
  994. joystick->hwdata->balls =
  995. (struct hwdata_ball *)SDL_calloc(joystick->nballs, sizeof(struct hwdata_ball));
  996. if (joystick->hwdata->balls == NULL) {
  997. return false;
  998. }
  999. return true;
  1000. }
  1001. static bool allocate_hatdata(SDL_Joystick *joystick)
  1002. {
  1003. int i;
  1004. SDL_AssertJoysticksLocked();
  1005. joystick->hwdata->hats =
  1006. (struct hwdata_hat *)SDL_malloc(joystick->nhats *
  1007. sizeof(struct hwdata_hat));
  1008. if (!joystick->hwdata->hats) {
  1009. return false;
  1010. }
  1011. for (i = 0; i < joystick->nhats; ++i) {
  1012. joystick->hwdata->hats[i].axis[0] = 1;
  1013. joystick->hwdata->hats[i].axis[1] = 1;
  1014. }
  1015. return true;
  1016. }
  1017. static bool GuessIfAxesAreDigitalHat(struct input_absinfo *absinfo_x, struct input_absinfo *absinfo_y)
  1018. {
  1019. /* A "hat" is assumed to be a digital input with at most 9 possible states
  1020. * (3 per axis: negative/zero/positive), as opposed to a true "axis" which
  1021. * can report a continuous range of possible values. Unfortunately the Linux
  1022. * joystick interface makes no distinction between digital hat axes and any
  1023. * other continuous analog axis, so we have to guess. */
  1024. // If both axes are missing, they're not anything.
  1025. if (!absinfo_x && !absinfo_y) {
  1026. return false;
  1027. }
  1028. // If the hint says so, treat all hats as digital.
  1029. if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_LINUX_DIGITAL_HATS, false)) {
  1030. return true;
  1031. }
  1032. // If both axes have ranges constrained between -1 and 1, they're definitely digital.
  1033. if ((!absinfo_x || (absinfo_x->minimum == -1 && absinfo_x->maximum == 1)) && (!absinfo_y || (absinfo_y->minimum == -1 && absinfo_y->maximum == 1))) {
  1034. return true;
  1035. }
  1036. // If both axes lack fuzz, flat, and resolution values, they're probably digital.
  1037. if ((!absinfo_x || (!absinfo_x->fuzz && !absinfo_x->flat && !absinfo_x->resolution)) && (!absinfo_y || (!absinfo_y->fuzz && !absinfo_y->flat && !absinfo_y->resolution))) {
  1038. return true;
  1039. }
  1040. // Otherwise, treat them as analog.
  1041. return false;
  1042. }
  1043. static void ConfigJoystick(SDL_Joystick *joystick, int fd, int fd_sensor)
  1044. {
  1045. int i, t;
  1046. unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
  1047. unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
  1048. unsigned long relbit[NBITS(REL_MAX)] = { 0 };
  1049. unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
  1050. Uint8 key_pam_size, abs_pam_size;
  1051. bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_LINUX_DEADZONES, false);
  1052. bool use_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_LINUX_HAT_DEADZONES, true);
  1053. SDL_AssertJoysticksLocked();
  1054. // See if this device uses the new unified event API
  1055. if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
  1056. (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
  1057. (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) {
  1058. // Get the number of buttons, axes, and other thingamajigs
  1059. for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
  1060. if (test_bit(i, keybit)) {
  1061. #ifdef DEBUG_INPUT_EVENTS
  1062. SDL_Log("Joystick has button: 0x%x", i);
  1063. #endif
  1064. joystick->hwdata->key_map[i] = joystick->nbuttons;
  1065. joystick->hwdata->has_key[i] = true;
  1066. ++joystick->nbuttons;
  1067. }
  1068. }
  1069. for (i = 0; i < BTN_JOYSTICK; ++i) {
  1070. if (test_bit(i, keybit)) {
  1071. #ifdef DEBUG_INPUT_EVENTS
  1072. SDL_Log("Joystick has button: 0x%x", i);
  1073. #endif
  1074. joystick->hwdata->key_map[i] = joystick->nbuttons;
  1075. joystick->hwdata->has_key[i] = true;
  1076. ++joystick->nbuttons;
  1077. }
  1078. }
  1079. for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
  1080. int hat_x = -1;
  1081. int hat_y = -1;
  1082. struct input_absinfo absinfo_x;
  1083. struct input_absinfo absinfo_y;
  1084. if (test_bit(i, absbit)) {
  1085. hat_x = ioctl(fd, EVIOCGABS(i), &absinfo_x);
  1086. }
  1087. if (test_bit(i + 1, absbit)) {
  1088. hat_y = ioctl(fd, EVIOCGABS(i + 1), &absinfo_y);
  1089. }
  1090. if (GuessIfAxesAreDigitalHat((hat_x < 0 ? (void *)0 : &absinfo_x),
  1091. (hat_y < 0 ? (void *)0 : &absinfo_y))) {
  1092. const int hat_index = (i - ABS_HAT0X) / 2;
  1093. struct hat_axis_correct *correct = &joystick->hwdata->hat_correct[hat_index];
  1094. #ifdef DEBUG_INPUT_EVENTS
  1095. SDL_Log("Joystick has digital hat: #%d", hat_index);
  1096. if (hat_x >= 0) {
  1097. SDL_Log("X Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }",
  1098. absinfo_x.value, absinfo_x.minimum, absinfo_x.maximum,
  1099. absinfo_x.fuzz, absinfo_x.flat, absinfo_x.resolution);
  1100. }
  1101. if (hat_y >= 0) {
  1102. SDL_Log("Y Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }",
  1103. absinfo_y.value, absinfo_y.minimum, absinfo_y.maximum,
  1104. absinfo_y.fuzz, absinfo_y.flat, absinfo_y.resolution);
  1105. }
  1106. #endif // DEBUG_INPUT_EVENTS
  1107. joystick->hwdata->hats_indices[hat_index] = joystick->nhats;
  1108. joystick->hwdata->has_hat[hat_index] = true;
  1109. correct->use_deadzones = use_hat_deadzones;
  1110. correct->minimum[0] = (hat_x < 0) ? -1 : absinfo_x.minimum;
  1111. correct->maximum[0] = (hat_x < 0) ? 1 : absinfo_x.maximum;
  1112. correct->minimum[1] = (hat_y < 0) ? -1 : absinfo_y.minimum;
  1113. correct->maximum[1] = (hat_y < 0) ? 1 : absinfo_y.maximum;
  1114. ++joystick->nhats;
  1115. }
  1116. }
  1117. for (i = 0; i < ABS_MAX; ++i) {
  1118. // Skip digital hats
  1119. if (i >= ABS_HAT0X && i <= ABS_HAT3Y && joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) {
  1120. continue;
  1121. }
  1122. if (test_bit(i, absbit)) {
  1123. struct input_absinfo absinfo;
  1124. struct axis_correct *correct = &joystick->hwdata->abs_correct[i];
  1125. if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
  1126. continue;
  1127. }
  1128. #ifdef DEBUG_INPUT_EVENTS
  1129. SDL_Log("Joystick has absolute axis: 0x%.2x", i);
  1130. SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }",
  1131. absinfo.value, absinfo.minimum, absinfo.maximum,
  1132. absinfo.fuzz, absinfo.flat, absinfo.resolution);
  1133. #endif // DEBUG_INPUT_EVENTS
  1134. joystick->hwdata->abs_map[i] = joystick->naxes;
  1135. joystick->hwdata->has_abs[i] = true;
  1136. correct->minimum = absinfo.minimum;
  1137. correct->maximum = absinfo.maximum;
  1138. if (correct->minimum != correct->maximum) {
  1139. if (use_deadzones) {
  1140. correct->use_deadzones = true;
  1141. correct->coef[0] = (absinfo.maximum + absinfo.minimum) - 2 * absinfo.flat;
  1142. correct->coef[1] = (absinfo.maximum + absinfo.minimum) + 2 * absinfo.flat;
  1143. t = ((absinfo.maximum - absinfo.minimum) - 4 * absinfo.flat);
  1144. if (t != 0) {
  1145. correct->coef[2] = (1 << 28) / t;
  1146. } else {
  1147. correct->coef[2] = 0;
  1148. }
  1149. } else {
  1150. float value_range = (correct->maximum - correct->minimum);
  1151. float output_range = (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN);
  1152. correct->scale = (output_range / value_range);
  1153. }
  1154. }
  1155. ++joystick->naxes;
  1156. }
  1157. }
  1158. if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) {
  1159. ++joystick->nballs;
  1160. }
  1161. } else if ((ioctl(fd, JSIOCGBUTTONS, &key_pam_size, sizeof(key_pam_size)) >= 0) &&
  1162. (ioctl(fd, JSIOCGAXES, &abs_pam_size, sizeof(abs_pam_size)) >= 0)) {
  1163. size_t len;
  1164. joystick->hwdata->classic = true;
  1165. len = (KEY_MAX - BTN_MISC + 1) * sizeof(*joystick->hwdata->key_pam);
  1166. joystick->hwdata->key_pam = (Uint16 *)SDL_calloc(1, len);
  1167. if (joystick->hwdata->key_pam) {
  1168. if (ioctl(fd, JSIOCGBTNMAP, joystick->hwdata->key_pam, len) < 0) {
  1169. SDL_free(joystick->hwdata->key_pam);
  1170. joystick->hwdata->key_pam = NULL;
  1171. key_pam_size = 0;
  1172. }
  1173. } else {
  1174. key_pam_size = 0;
  1175. }
  1176. for (i = 0; i < key_pam_size; ++i) {
  1177. Uint16 code = joystick->hwdata->key_pam[i];
  1178. #ifdef DEBUG_INPUT_EVENTS
  1179. SDL_Log("Joystick has button: 0x%x", code);
  1180. #endif
  1181. joystick->hwdata->key_map[code] = joystick->nbuttons;
  1182. joystick->hwdata->has_key[code] = true;
  1183. ++joystick->nbuttons;
  1184. }
  1185. len = ABS_CNT * sizeof(*joystick->hwdata->abs_pam);
  1186. joystick->hwdata->abs_pam = (Uint8 *)SDL_calloc(1, len);
  1187. if (joystick->hwdata->abs_pam) {
  1188. if (ioctl(fd, JSIOCGAXMAP, joystick->hwdata->abs_pam, len) < 0) {
  1189. SDL_free(joystick->hwdata->abs_pam);
  1190. joystick->hwdata->abs_pam = NULL;
  1191. abs_pam_size = 0;
  1192. }
  1193. } else {
  1194. abs_pam_size = 0;
  1195. }
  1196. for (i = 0; i < abs_pam_size; ++i) {
  1197. Uint8 code = joystick->hwdata->abs_pam[i];
  1198. // TODO: is there any way to detect analog hats in advance via this API?
  1199. if (code >= ABS_HAT0X && code <= ABS_HAT3Y) {
  1200. int hat_index = (code - ABS_HAT0X) / 2;
  1201. if (!joystick->hwdata->has_hat[hat_index]) {
  1202. #ifdef DEBUG_INPUT_EVENTS
  1203. SDL_Log("Joystick has digital hat: #%d", hat_index);
  1204. #endif
  1205. joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
  1206. joystick->hwdata->has_hat[hat_index] = true;
  1207. joystick->hwdata->hat_correct[hat_index].minimum[0] = -1;
  1208. joystick->hwdata->hat_correct[hat_index].maximum[0] = 1;
  1209. joystick->hwdata->hat_correct[hat_index].minimum[1] = -1;
  1210. joystick->hwdata->hat_correct[hat_index].maximum[1] = 1;
  1211. }
  1212. } else {
  1213. #ifdef DEBUG_INPUT_EVENTS
  1214. SDL_Log("Joystick has absolute axis: 0x%.2x", code);
  1215. #endif
  1216. joystick->hwdata->abs_map[code] = joystick->naxes;
  1217. joystick->hwdata->has_abs[code] = true;
  1218. ++joystick->naxes;
  1219. }
  1220. }
  1221. }
  1222. // Sensors are only available through the new unified event API
  1223. if (fd_sensor >= 0 && (ioctl(fd_sensor, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0)) {
  1224. if (test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) && test_bit(ABS_Z, absbit)) {
  1225. joystick->hwdata->has_accelerometer = true;
  1226. for (i = 0; i < 3; ++i) {
  1227. struct input_absinfo absinfo;
  1228. if (ioctl(fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) < 0) {
  1229. joystick->hwdata->has_accelerometer = false;
  1230. break; // do not report an accelerometer if we can't read all axes
  1231. }
  1232. joystick->hwdata->accelerometer_scale[i] = absinfo.resolution;
  1233. #ifdef DEBUG_INPUT_EVENTS
  1234. SDL_Log("Joystick has accelerometer axis: 0x%.2x", ABS_X + i);
  1235. SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }",
  1236. absinfo.value, absinfo.minimum, absinfo.maximum,
  1237. absinfo.fuzz, absinfo.flat, absinfo.resolution);
  1238. #endif // DEBUG_INPUT_EVENTS
  1239. }
  1240. }
  1241. if (test_bit(ABS_RX, absbit) && test_bit(ABS_RY, absbit) && test_bit(ABS_RZ, absbit)) {
  1242. joystick->hwdata->has_gyro = true;
  1243. for (i = 0; i < 3; ++i) {
  1244. struct input_absinfo absinfo;
  1245. if (ioctl(fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) < 0) {
  1246. joystick->hwdata->has_gyro = false;
  1247. break; // do not report a gyro if we can't read all axes
  1248. }
  1249. joystick->hwdata->gyro_scale[i] = absinfo.resolution;
  1250. #ifdef DEBUG_INPUT_EVENTS
  1251. SDL_Log("Joystick has gyro axis: 0x%.2x", ABS_RX + i);
  1252. SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }",
  1253. absinfo.value, absinfo.minimum, absinfo.maximum,
  1254. absinfo.fuzz, absinfo.flat, absinfo.resolution);
  1255. #endif // DEBUG_INPUT_EVENTS
  1256. }
  1257. }
  1258. }
  1259. // Allocate data to keep track of these thingamajigs
  1260. if (joystick->nballs > 0) {
  1261. if (!allocate_balldata(joystick)) {
  1262. joystick->nballs = 0;
  1263. }
  1264. }
  1265. if (joystick->nhats > 0) {
  1266. if (!allocate_hatdata(joystick)) {
  1267. joystick->nhats = 0;
  1268. }
  1269. }
  1270. if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0) {
  1271. if (test_bit(FF_RUMBLE, ffbit)) {
  1272. joystick->hwdata->ff_rumble = true;
  1273. }
  1274. if (test_bit(FF_SINE, ffbit)) {
  1275. joystick->hwdata->ff_sine = true;
  1276. }
  1277. }
  1278. }
  1279. /* This is used to do the heavy lifting for LINUX_JoystickOpen and
  1280. also LINUX_JoystickGetGamepadMapping, so we can query the hardware
  1281. without adding an opened SDL_Joystick object to the system.
  1282. This expects `joystick->hwdata` to be allocated and will not free it
  1283. on error. Returns -1 on error, 0 on success. */
  1284. static bool PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item, SDL_sensorlist_item *item_sensor)
  1285. {
  1286. SDL_AssertJoysticksLocked();
  1287. joystick->hwdata->item = item;
  1288. joystick->hwdata->item_sensor = item_sensor;
  1289. joystick->hwdata->guid = item->guid;
  1290. joystick->hwdata->effect.id = -1;
  1291. SDL_memset(joystick->hwdata->key_map, 0xFF, sizeof(joystick->hwdata->key_map));
  1292. SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map));
  1293. int fd = -1, fd_sensor = -1;
  1294. // Try read-write first, so we can do rumble
  1295. fd = open(item->path, O_RDWR | O_CLOEXEC, 0);
  1296. if (fd < 0) {
  1297. // Try read-only again, at least we'll get events in this case
  1298. fd = open(item->path, O_RDONLY | O_CLOEXEC, 0);
  1299. }
  1300. if (fd < 0) {
  1301. return SDL_SetError("Unable to open %s", item->path);
  1302. }
  1303. // If opening sensor fail, continue with buttons and axes only
  1304. if (item_sensor) {
  1305. fd_sensor = open(item_sensor->path, O_RDONLY | O_CLOEXEC, 0);
  1306. }
  1307. joystick->hwdata->fd = fd;
  1308. joystick->hwdata->fd_sensor = fd_sensor;
  1309. joystick->hwdata->fname = SDL_strdup(item->path);
  1310. if (!joystick->hwdata->fname) {
  1311. close(fd);
  1312. if (fd_sensor >= 0) {
  1313. close(fd_sensor);
  1314. }
  1315. return false;
  1316. }
  1317. // Set the joystick to non-blocking read mode
  1318. fcntl(fd, F_SETFL, O_NONBLOCK);
  1319. if (fd_sensor >= 0) {
  1320. fcntl(fd_sensor, F_SETFL, O_NONBLOCK);
  1321. }
  1322. // Get the number of buttons and axes on the joystick
  1323. ConfigJoystick(joystick, fd, fd_sensor);
  1324. return true;
  1325. }
  1326. static SDL_sensorlist_item *GetSensor(SDL_joylist_item *item)
  1327. {
  1328. SDL_sensorlist_item *item_sensor;
  1329. char uniq_item[128];
  1330. int fd_item = -1;
  1331. SDL_AssertJoysticksLocked();
  1332. if (!item || !SDL_sensorlist) {
  1333. return NULL;
  1334. }
  1335. SDL_memset(uniq_item, 0, sizeof(uniq_item));
  1336. fd_item = open(item->path, O_RDONLY | O_CLOEXEC, 0);
  1337. if (fd_item < 0) {
  1338. return NULL;
  1339. }
  1340. if (ioctl(fd_item, EVIOCGUNIQ(sizeof(uniq_item) - 1), &uniq_item) < 0) {
  1341. close(fd_item);
  1342. return NULL;
  1343. }
  1344. close(fd_item);
  1345. #ifdef DEBUG_INPUT_EVENTS
  1346. SDL_Log("Joystick UNIQ: %s", uniq_item);
  1347. #endif // DEBUG_INPUT_EVENTS
  1348. for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = item_sensor->next) {
  1349. char uniq_sensor[128];
  1350. int fd_sensor = -1;
  1351. if (item_sensor->hwdata) {
  1352. // already associated with another joystick
  1353. continue;
  1354. }
  1355. SDL_memset(uniq_sensor, 0, sizeof(uniq_sensor));
  1356. fd_sensor = open(item_sensor->path, O_RDONLY | O_CLOEXEC, 0);
  1357. if (fd_sensor < 0) {
  1358. continue;
  1359. }
  1360. if (ioctl(fd_sensor, EVIOCGUNIQ(sizeof(uniq_sensor) - 1), &uniq_sensor) < 0) {
  1361. close(fd_sensor);
  1362. continue;
  1363. }
  1364. close(fd_sensor);
  1365. #ifdef DEBUG_INPUT_EVENTS
  1366. SDL_Log("Sensor UNIQ: %s", uniq_sensor);
  1367. #endif // DEBUG_INPUT_EVENTS
  1368. if (SDL_strcmp(uniq_item, uniq_sensor) == 0) {
  1369. return item_sensor;
  1370. }
  1371. }
  1372. return NULL;
  1373. }
  1374. static bool LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index)
  1375. {
  1376. SDL_joylist_item *item;
  1377. SDL_sensorlist_item *item_sensor;
  1378. SDL_AssertJoysticksLocked();
  1379. item = GetJoystickByDevIndex(device_index);
  1380. if (!item) {
  1381. return SDL_SetError("No such device");
  1382. }
  1383. joystick->hwdata = (struct joystick_hwdata *)
  1384. SDL_calloc(1, sizeof(*joystick->hwdata));
  1385. if (!joystick->hwdata) {
  1386. return false;
  1387. }
  1388. item_sensor = GetSensor(item);
  1389. if (!PrepareJoystickHwdata(joystick, item, item_sensor)) {
  1390. SDL_free(joystick->hwdata);
  1391. joystick->hwdata = NULL;
  1392. return false; // SDL_SetError will already have been called
  1393. }
  1394. SDL_assert(item->hwdata == NULL);
  1395. SDL_assert(!item_sensor || item_sensor->hwdata == NULL);
  1396. item->hwdata = joystick->hwdata;
  1397. if (item_sensor) {
  1398. item_sensor->hwdata = joystick->hwdata;
  1399. }
  1400. // mark joystick as fresh and ready
  1401. joystick->hwdata->fresh = true;
  1402. if (joystick->hwdata->has_gyro) {
  1403. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f);
  1404. }
  1405. if (joystick->hwdata->has_accelerometer) {
  1406. SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f);
  1407. }
  1408. if (joystick->hwdata->fd_sensor >= 0) {
  1409. // Don't keep fd_sensor opened while sensor is disabled
  1410. close(joystick->hwdata->fd_sensor);
  1411. joystick->hwdata->fd_sensor = -1;
  1412. }
  1413. if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) {
  1414. SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true);
  1415. }
  1416. return true;
  1417. }
  1418. static bool LINUX_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
  1419. {
  1420. struct input_event event;
  1421. SDL_AssertJoysticksLocked();
  1422. if (joystick->hwdata->ff_rumble) {
  1423. struct ff_effect *effect = &joystick->hwdata->effect;
  1424. effect->type = FF_RUMBLE;
  1425. effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
  1426. effect->u.rumble.strong_magnitude = low_frequency_rumble;
  1427. effect->u.rumble.weak_magnitude = high_frequency_rumble;
  1428. } else if (joystick->hwdata->ff_sine) {
  1429. // Scale and average the two rumble strengths
  1430. Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2);
  1431. struct ff_effect *effect = &joystick->hwdata->effect;
  1432. effect->type = FF_PERIODIC;
  1433. effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
  1434. effect->u.periodic.waveform = FF_SINE;
  1435. effect->u.periodic.magnitude = magnitude;
  1436. } else {
  1437. return SDL_Unsupported();
  1438. }
  1439. if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) {
  1440. // The kernel may have lost this effect, try to allocate a new one
  1441. joystick->hwdata->effect.id = -1;
  1442. if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) {
  1443. return SDL_SetError("Couldn't update rumble effect: %s", strerror(errno));
  1444. }
  1445. }
  1446. event.type = EV_FF;
  1447. event.code = joystick->hwdata->effect.id;
  1448. event.value = 1;
  1449. if (write(joystick->hwdata->fd, &event, sizeof(event)) < 0) {
  1450. return SDL_SetError("Couldn't start rumble effect: %s", strerror(errno));
  1451. }
  1452. return true;
  1453. }
  1454. static bool LINUX_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
  1455. {
  1456. return SDL_Unsupported();
  1457. }
  1458. static bool LINUX_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
  1459. {
  1460. return SDL_Unsupported();
  1461. }
  1462. static bool LINUX_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
  1463. {
  1464. return SDL_Unsupported();
  1465. }
  1466. static bool LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled)
  1467. {
  1468. SDL_AssertJoysticksLocked();
  1469. if (!joystick->hwdata->has_accelerometer && !joystick->hwdata->has_gyro) {
  1470. return SDL_Unsupported();
  1471. }
  1472. if (enabled == joystick->hwdata->report_sensor) {
  1473. return true;
  1474. }
  1475. if (enabled) {
  1476. if (!joystick->hwdata->item_sensor) {
  1477. return SDL_SetError("Sensors unplugged.");
  1478. }
  1479. joystick->hwdata->fd_sensor = open(joystick->hwdata->item_sensor->path, O_RDONLY | O_CLOEXEC, 0);
  1480. if (joystick->hwdata->fd_sensor < 0) {
  1481. return SDL_SetError("Couldn't open sensor file %s.", joystick->hwdata->item_sensor->path);
  1482. }
  1483. fcntl(joystick->hwdata->fd_sensor, F_SETFL, O_NONBLOCK);
  1484. } else {
  1485. SDL_assert(joystick->hwdata->fd_sensor >= 0);
  1486. close(joystick->hwdata->fd_sensor);
  1487. joystick->hwdata->fd_sensor = -1;
  1488. }
  1489. joystick->hwdata->report_sensor = enabled;
  1490. return true;
  1491. }
  1492. static void HandleHat(Uint64 timestamp, SDL_Joystick *stick, int hatidx, int axis, int value)
  1493. {
  1494. int hatnum;
  1495. struct hwdata_hat *the_hat;
  1496. struct hat_axis_correct *correct;
  1497. const Uint8 position_map[3][3] = {
  1498. { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
  1499. { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
  1500. { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
  1501. };
  1502. SDL_AssertJoysticksLocked();
  1503. hatnum = stick->hwdata->hats_indices[hatidx];
  1504. the_hat = &stick->hwdata->hats[hatnum];
  1505. correct = &stick->hwdata->hat_correct[hatidx];
  1506. /* Hopefully we detected any analog axes and left them as is rather than trying
  1507. * to use them as digital hats, but just in case, the deadzones here will
  1508. * prevent the slightest of twitches on an analog axis from registering as a hat
  1509. * movement. If the axes really are digital, this won't hurt since they should
  1510. * only ever be sending min, 0, or max anyway. */
  1511. if (value < 0) {
  1512. if (value <= correct->minimum[axis]) {
  1513. correct->minimum[axis] = value;
  1514. value = 0;
  1515. } else if (!correct->use_deadzones || value < correct->minimum[axis] / 3) {
  1516. value = 0;
  1517. } else {
  1518. value = 1;
  1519. }
  1520. } else if (value > 0) {
  1521. if (value >= correct->maximum[axis]) {
  1522. correct->maximum[axis] = value;
  1523. value = 2;
  1524. } else if (!correct->use_deadzones || value > correct->maximum[axis] / 3) {
  1525. value = 2;
  1526. } else {
  1527. value = 1;
  1528. }
  1529. } else { // value == 0
  1530. value = 1;
  1531. }
  1532. if (value != the_hat->axis[axis]) {
  1533. the_hat->axis[axis] = value;
  1534. SDL_SendJoystickHat(timestamp, stick, hatnum,
  1535. position_map[the_hat->axis[1]][the_hat->axis[0]]);
  1536. }
  1537. }
  1538. static void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
  1539. {
  1540. stick->hwdata->balls[ball].axis[axis] += value;
  1541. }
  1542. static int AxisCorrect(SDL_Joystick *joystick, int which, int value)
  1543. {
  1544. struct axis_correct *correct;
  1545. SDL_AssertJoysticksLocked();
  1546. correct = &joystick->hwdata->abs_correct[which];
  1547. if (correct->minimum != correct->maximum) {
  1548. if (correct->use_deadzones) {
  1549. value *= 2;
  1550. if (value > correct->coef[0]) {
  1551. if (value < correct->coef[1]) {
  1552. return 0;
  1553. }
  1554. value -= correct->coef[1];
  1555. } else {
  1556. value -= correct->coef[0];
  1557. }
  1558. value *= correct->coef[2];
  1559. value >>= 13;
  1560. } else {
  1561. value = (int)SDL_floorf((value - correct->minimum) * correct->scale + SDL_JOYSTICK_AXIS_MIN + 0.5f);
  1562. }
  1563. }
  1564. // Clamp and return
  1565. if (value < SDL_JOYSTICK_AXIS_MIN) {
  1566. return SDL_JOYSTICK_AXIS_MIN;
  1567. }
  1568. if (value > SDL_JOYSTICK_AXIS_MAX) {
  1569. return SDL_JOYSTICK_AXIS_MAX;
  1570. }
  1571. return value;
  1572. }
  1573. static void PollAllValues(Uint64 timestamp, SDL_Joystick *joystick)
  1574. {
  1575. struct input_absinfo absinfo;
  1576. unsigned long keyinfo[NBITS(KEY_MAX)];
  1577. int i;
  1578. SDL_AssertJoysticksLocked();
  1579. // Poll all axis
  1580. for (i = ABS_X; i < ABS_MAX; i++) {
  1581. // We don't need to test for digital hats here, they won't have has_abs[] set
  1582. if (joystick->hwdata->has_abs[i]) {
  1583. if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
  1584. absinfo.value = AxisCorrect(joystick, i, absinfo.value);
  1585. #ifdef DEBUG_INPUT_EVENTS
  1586. SDL_Log("Joystick : Re-read Axis %d (%d) val= %d",
  1587. joystick->hwdata->abs_map[i], i, absinfo.value);
  1588. #endif
  1589. SDL_SendJoystickAxis(timestamp, joystick,
  1590. joystick->hwdata->abs_map[i],
  1591. absinfo.value);
  1592. }
  1593. }
  1594. }
  1595. // Poll all digital hats
  1596. for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++) {
  1597. const int baseaxis = i - ABS_HAT0X;
  1598. const int hatidx = baseaxis / 2;
  1599. SDL_assert(hatidx < SDL_arraysize(joystick->hwdata->has_hat));
  1600. // We don't need to test for analog axes here, they won't have has_hat[] set
  1601. if (joystick->hwdata->has_hat[hatidx]) {
  1602. if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
  1603. const int hataxis = baseaxis % 2;
  1604. HandleHat(timestamp, joystick, hatidx, hataxis, absinfo.value);
  1605. }
  1606. }
  1607. }
  1608. // Poll all buttons
  1609. SDL_zeroa(keyinfo);
  1610. if (ioctl(joystick->hwdata->fd, EVIOCGKEY(sizeof(keyinfo)), keyinfo) >= 0) {
  1611. for (i = 0; i < KEY_MAX; i++) {
  1612. if (joystick->hwdata->has_key[i]) {
  1613. bool down = test_bit(i, keyinfo);
  1614. #ifdef DEBUG_INPUT_EVENTS
  1615. SDL_Log("Joystick : Re-read Button %d (%d) val= %d",
  1616. joystick->hwdata->key_map[i], i, down);
  1617. #endif
  1618. SDL_SendJoystickButton(timestamp, joystick,
  1619. joystick->hwdata->key_map[i], down);
  1620. }
  1621. }
  1622. }
  1623. // Joyballs are relative input, so there's no poll state. Events only!
  1624. }
  1625. static void PollAllSensors(Uint64 timestamp, SDL_Joystick *joystick)
  1626. {
  1627. struct input_absinfo absinfo;
  1628. int i;
  1629. SDL_AssertJoysticksLocked();
  1630. SDL_assert(joystick->hwdata->fd_sensor >= 0);
  1631. if (joystick->hwdata->has_gyro) {
  1632. float data[3] = {0.0f, 0.0f, 0.0f};
  1633. for (i = 0; i < 3; i++) {
  1634. if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) >= 0) {
  1635. data[i] = absinfo.value * (SDL_PI_F / 180.f) / joystick->hwdata->gyro_scale[i];
  1636. #ifdef DEBUG_INPUT_EVENTS
  1637. SDL_Log("Joystick : Re-read Gyro (axis %d) val= %f", i, data[i]);
  1638. #endif
  1639. }
  1640. }
  1641. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, SDL_US_TO_NS(joystick->hwdata->sensor_tick), data, 3);
  1642. }
  1643. if (joystick->hwdata->has_accelerometer) {
  1644. float data[3] = {0.0f, 0.0f, 0.0f};
  1645. for (i = 0; i < 3; i++) {
  1646. if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) >= 0) {
  1647. data[i] = absinfo.value * SDL_STANDARD_GRAVITY / joystick->hwdata->accelerometer_scale[i];
  1648. #ifdef DEBUG_INPUT_EVENTS
  1649. SDL_Log("Joystick : Re-read Accelerometer (axis %d) val= %f", i, data[i]);
  1650. #endif
  1651. }
  1652. }
  1653. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, SDL_US_TO_NS(joystick->hwdata->sensor_tick), data, 3);
  1654. }
  1655. }
  1656. static void HandleInputEvents(SDL_Joystick *joystick)
  1657. {
  1658. struct input_event events[32];
  1659. int i, len, code, hat_index;
  1660. SDL_AssertJoysticksLocked();
  1661. if (joystick->hwdata->fresh) {
  1662. Uint64 ticks = SDL_GetTicksNS();
  1663. PollAllValues(ticks, joystick);
  1664. if (joystick->hwdata->report_sensor) {
  1665. PollAllSensors(ticks, joystick);
  1666. }
  1667. joystick->hwdata->fresh = false;
  1668. }
  1669. errno = 0;
  1670. while ((len = read(joystick->hwdata->fd, events, sizeof(events))) > 0) {
  1671. len /= sizeof(events[0]);
  1672. for (i = 0; i < len; ++i) {
  1673. struct input_event *event = &events[i];
  1674. code = event->code;
  1675. /* If the kernel sent a SYN_DROPPED, we are supposed to ignore the
  1676. rest of the packet (the end of it signified by a SYN_REPORT) */
  1677. if (joystick->hwdata->recovering_from_dropped &&
  1678. ((event->type != EV_SYN) || (code != SYN_REPORT))) {
  1679. continue;
  1680. }
  1681. switch (event->type) {
  1682. case EV_KEY:
  1683. #ifdef DEBUG_INPUT_EVENTS
  1684. SDL_Log("Key 0x%.2x %s", code, event->value ? "PRESSED" : "RELEASED");
  1685. #endif
  1686. SDL_SendJoystickButton(SDL_EVDEV_GetEventTimestamp(event), joystick,
  1687. joystick->hwdata->key_map[code],
  1688. (event->value != 0));
  1689. break;
  1690. case EV_ABS:
  1691. switch (code) {
  1692. case ABS_HAT0X:
  1693. case ABS_HAT0Y:
  1694. case ABS_HAT1X:
  1695. case ABS_HAT1Y:
  1696. case ABS_HAT2X:
  1697. case ABS_HAT2Y:
  1698. case ABS_HAT3X:
  1699. case ABS_HAT3Y:
  1700. hat_index = (code - ABS_HAT0X) / 2;
  1701. if (joystick->hwdata->has_hat[hat_index]) {
  1702. #ifdef DEBUG_INPUT_EVENTS
  1703. SDL_Log("Axis 0x%.2x = %d", code, event->value);
  1704. #endif
  1705. HandleHat(SDL_EVDEV_GetEventTimestamp(event), joystick, hat_index, code % 2, event->value);
  1706. break;
  1707. }
  1708. SDL_FALLTHROUGH;
  1709. default:
  1710. #ifdef DEBUG_INPUT_EVENTS
  1711. SDL_Log("Axis 0x%.2x = %d", code, event->value);
  1712. #endif
  1713. event->value = AxisCorrect(joystick, code, event->value);
  1714. SDL_SendJoystickAxis(SDL_EVDEV_GetEventTimestamp(event), joystick,
  1715. joystick->hwdata->abs_map[code],
  1716. event->value);
  1717. break;
  1718. }
  1719. break;
  1720. case EV_REL:
  1721. switch (code) {
  1722. case REL_X:
  1723. case REL_Y:
  1724. code -= REL_X;
  1725. HandleBall(joystick, code / 2, code % 2, event->value);
  1726. break;
  1727. default:
  1728. break;
  1729. }
  1730. break;
  1731. case EV_SYN:
  1732. switch (code) {
  1733. case SYN_DROPPED:
  1734. #ifdef DEBUG_INPUT_EVENTS
  1735. SDL_Log("Event SYN_DROPPED detected");
  1736. #endif
  1737. joystick->hwdata->recovering_from_dropped = true;
  1738. break;
  1739. case SYN_REPORT:
  1740. if (joystick->hwdata->recovering_from_dropped) {
  1741. joystick->hwdata->recovering_from_dropped = false;
  1742. PollAllValues(SDL_GetTicksNS(), joystick); // try to sync up to current state now
  1743. }
  1744. break;
  1745. default:
  1746. break;
  1747. }
  1748. break;
  1749. default:
  1750. break;
  1751. }
  1752. }
  1753. }
  1754. if (errno == ENODEV) {
  1755. // We have to wait until the JoystickDetect callback to remove this
  1756. joystick->hwdata->gone = true;
  1757. errno = 0;
  1758. }
  1759. if (joystick->hwdata->report_sensor) {
  1760. SDL_assert(joystick->hwdata->fd_sensor >= 0);
  1761. while ((len = read(joystick->hwdata->fd_sensor, events, sizeof(events))) > 0) {
  1762. len /= sizeof(events[0]);
  1763. for (i = 0; i < len; ++i) {
  1764. unsigned int j;
  1765. struct input_event *event = &events[i];
  1766. code = event->code;
  1767. /* If the kernel sent a SYN_DROPPED, we are supposed to ignore the
  1768. rest of the packet (the end of it signified by a SYN_REPORT) */
  1769. if (joystick->hwdata->recovering_from_dropped_sensor &&
  1770. ((event->type != EV_SYN) || (code != SYN_REPORT))) {
  1771. continue;
  1772. }
  1773. switch (event->type) {
  1774. case EV_KEY:
  1775. SDL_assert(0);
  1776. break;
  1777. case EV_ABS:
  1778. switch (code) {
  1779. case ABS_X:
  1780. case ABS_Y:
  1781. case ABS_Z:
  1782. j = code - ABS_X;
  1783. joystick->hwdata->accel_data[j] = event->value * SDL_STANDARD_GRAVITY
  1784. / joystick->hwdata->accelerometer_scale[j];
  1785. break;
  1786. case ABS_RX:
  1787. case ABS_RY:
  1788. case ABS_RZ:
  1789. j = code - ABS_RX;
  1790. joystick->hwdata->gyro_data[j] = event->value * (SDL_PI_F / 180.f)
  1791. / joystick->hwdata->gyro_scale[j];
  1792. break;
  1793. }
  1794. break;
  1795. case EV_MSC:
  1796. if (code == MSC_TIMESTAMP) {
  1797. Sint32 tick = event->value;
  1798. Sint32 delta;
  1799. if (joystick->hwdata->last_tick < tick) {
  1800. delta = (tick - joystick->hwdata->last_tick);
  1801. } else {
  1802. delta = (SDL_MAX_SINT32 - joystick->hwdata->last_tick + tick + 1);
  1803. }
  1804. joystick->hwdata->sensor_tick += delta;
  1805. joystick->hwdata->last_tick = tick;
  1806. }
  1807. break;
  1808. case EV_SYN:
  1809. switch (code) {
  1810. case SYN_DROPPED:
  1811. #ifdef DEBUG_INPUT_EVENTS
  1812. SDL_Log("Event SYN_DROPPED detected");
  1813. #endif
  1814. joystick->hwdata->recovering_from_dropped_sensor = true;
  1815. break;
  1816. case SYN_REPORT:
  1817. if (joystick->hwdata->recovering_from_dropped_sensor) {
  1818. joystick->hwdata->recovering_from_dropped_sensor = false;
  1819. PollAllSensors(SDL_GetTicksNS(), joystick); // try to sync up to current state now
  1820. } else {
  1821. Uint64 timestamp = SDL_EVDEV_GetEventTimestamp(event);
  1822. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO,
  1823. SDL_US_TO_NS(joystick->hwdata->sensor_tick),
  1824. joystick->hwdata->gyro_data, 3);
  1825. SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL,
  1826. SDL_US_TO_NS(joystick->hwdata->sensor_tick),
  1827. joystick->hwdata->accel_data, 3);
  1828. }
  1829. break;
  1830. default:
  1831. break;
  1832. }
  1833. break;
  1834. default:
  1835. break;
  1836. }
  1837. }
  1838. }
  1839. }
  1840. if (errno == ENODEV) {
  1841. // We have to wait until the JoystickDetect callback to remove this
  1842. joystick->hwdata->sensor_gone = true;
  1843. }
  1844. }
  1845. static void HandleClassicEvents(SDL_Joystick *joystick)
  1846. {
  1847. struct js_event events[32];
  1848. int i, len, code, hat_index;
  1849. Uint64 timestamp = SDL_GetTicksNS();
  1850. SDL_AssertJoysticksLocked();
  1851. joystick->hwdata->fresh = false;
  1852. while ((len = read(joystick->hwdata->fd, events, sizeof(events))) > 0) {
  1853. len /= sizeof(events[0]);
  1854. for (i = 0; i < len; ++i) {
  1855. switch (events[i].type) {
  1856. case JS_EVENT_BUTTON:
  1857. code = joystick->hwdata->key_pam[events[i].number];
  1858. SDL_SendJoystickButton(timestamp, joystick,
  1859. joystick->hwdata->key_map[code],
  1860. (events[i].value != 0));
  1861. break;
  1862. case JS_EVENT_AXIS:
  1863. code = joystick->hwdata->abs_pam[events[i].number];
  1864. switch (code) {
  1865. case ABS_HAT0X:
  1866. case ABS_HAT0Y:
  1867. case ABS_HAT1X:
  1868. case ABS_HAT1Y:
  1869. case ABS_HAT2X:
  1870. case ABS_HAT2Y:
  1871. case ABS_HAT3X:
  1872. case ABS_HAT3Y:
  1873. hat_index = (code - ABS_HAT0X) / 2;
  1874. if (joystick->hwdata->has_hat[hat_index]) {
  1875. HandleHat(timestamp, joystick, hat_index, code % 2, events[i].value);
  1876. break;
  1877. }
  1878. SDL_FALLTHROUGH;
  1879. default:
  1880. SDL_SendJoystickAxis(timestamp, joystick,
  1881. joystick->hwdata->abs_map[code],
  1882. events[i].value);
  1883. break;
  1884. }
  1885. }
  1886. }
  1887. }
  1888. }
  1889. static void LINUX_JoystickUpdate(SDL_Joystick *joystick)
  1890. {
  1891. int i;
  1892. SDL_AssertJoysticksLocked();
  1893. if (joystick->hwdata->classic) {
  1894. HandleClassicEvents(joystick);
  1895. } else {
  1896. HandleInputEvents(joystick);
  1897. }
  1898. // Deliver ball motion updates
  1899. for (i = 0; i < joystick->nballs; ++i) {
  1900. int xrel, yrel;
  1901. xrel = joystick->hwdata->balls[i].axis[0];
  1902. yrel = joystick->hwdata->balls[i].axis[1];
  1903. if (xrel || yrel) {
  1904. joystick->hwdata->balls[i].axis[0] = 0;
  1905. joystick->hwdata->balls[i].axis[1] = 0;
  1906. SDL_SendJoystickBall(0, joystick, (Uint8)i, xrel, yrel);
  1907. }
  1908. }
  1909. }
  1910. // Function to close a joystick after use
  1911. static void LINUX_JoystickClose(SDL_Joystick *joystick)
  1912. {
  1913. SDL_AssertJoysticksLocked();
  1914. if (joystick->hwdata) {
  1915. if (joystick->hwdata->effect.id >= 0) {
  1916. ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
  1917. joystick->hwdata->effect.id = -1;
  1918. }
  1919. if (joystick->hwdata->fd >= 0) {
  1920. close(joystick->hwdata->fd);
  1921. }
  1922. if (joystick->hwdata->fd_sensor >= 0) {
  1923. close(joystick->hwdata->fd_sensor);
  1924. }
  1925. if (joystick->hwdata->item) {
  1926. joystick->hwdata->item->hwdata = NULL;
  1927. }
  1928. if (joystick->hwdata->item_sensor) {
  1929. joystick->hwdata->item_sensor->hwdata = NULL;
  1930. }
  1931. SDL_free(joystick->hwdata->key_pam);
  1932. SDL_free(joystick->hwdata->abs_pam);
  1933. SDL_free(joystick->hwdata->hats);
  1934. SDL_free(joystick->hwdata->balls);
  1935. SDL_free(joystick->hwdata->fname);
  1936. SDL_free(joystick->hwdata);
  1937. }
  1938. }
  1939. // Function to perform any system-specific joystick related cleanup
  1940. static void LINUX_JoystickQuit(void)
  1941. {
  1942. SDL_joylist_item *item = NULL;
  1943. SDL_joylist_item *next = NULL;
  1944. SDL_sensorlist_item *item_sensor = NULL;
  1945. SDL_sensorlist_item *next_sensor = NULL;
  1946. SDL_AssertJoysticksLocked();
  1947. if (inotify_fd >= 0) {
  1948. close(inotify_fd);
  1949. inotify_fd = -1;
  1950. }
  1951. for (item = SDL_joylist; item; item = next) {
  1952. next = item->next;
  1953. FreeJoylistItem(item);
  1954. }
  1955. for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = next_sensor) {
  1956. next_sensor = item_sensor->next;
  1957. FreeSensorlistItem(item_sensor);
  1958. }
  1959. SDL_joylist = SDL_joylist_tail = NULL;
  1960. SDL_sensorlist = NULL;
  1961. numjoysticks = 0;
  1962. #ifdef SDL_USE_LIBUDEV
  1963. if (enumeration_method == ENUMERATION_LIBUDEV) {
  1964. SDL_UDEV_DelCallback(joystick_udev_callback);
  1965. SDL_UDEV_Quit();
  1966. }
  1967. #endif
  1968. }
  1969. /*
  1970. This is based on the Linux Gamepad Specification
  1971. available at: https://www.kernel.org/doc/html/v4.15/input/gamepad.html
  1972. and the Android gamepad documentation,
  1973. https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input
  1974. */
  1975. static bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
  1976. {
  1977. SDL_Joystick *joystick;
  1978. SDL_joylist_item *item = GetJoystickByDevIndex(device_index);
  1979. enum {
  1980. MAPPED_TRIGGER_LEFT = 0x1,
  1981. MAPPED_TRIGGER_RIGHT = 0x2,
  1982. MAPPED_TRIGGER_BOTH = 0x3,
  1983. MAPPED_DPAD_UP = 0x1,
  1984. MAPPED_DPAD_DOWN = 0x2,
  1985. MAPPED_DPAD_LEFT = 0x4,
  1986. MAPPED_DPAD_RIGHT = 0x8,
  1987. MAPPED_DPAD_ALL = 0xF,
  1988. MAPPED_LEFT_PADDLE1 = 0x1,
  1989. MAPPED_RIGHT_PADDLE1 = 0x2,
  1990. MAPPED_LEFT_PADDLE2 = 0x4,
  1991. MAPPED_RIGHT_PADDLE2 = 0x8,
  1992. MAPPED_PADDLE_ALL = 0xF,
  1993. };
  1994. unsigned int mapped;
  1995. bool result = false;
  1996. SDL_AssertJoysticksLocked();
  1997. if (item->checked_mapping) {
  1998. if (item->mapping) {
  1999. SDL_memcpy(out, item->mapping, sizeof(*out));
  2000. #ifdef DEBUG_GAMEPAD_MAPPING
  2001. SDL_Log("Prior mapping for device %d", device_index);
  2002. #endif
  2003. return true;
  2004. } else {
  2005. return false;
  2006. }
  2007. }
  2008. /* We temporarily open the device to check how it's configured. Make
  2009. a fake SDL_Joystick object to do so. */
  2010. joystick = (SDL_Joystick *)SDL_calloc(1, sizeof(*joystick));
  2011. if (!joystick) {
  2012. return false;
  2013. }
  2014. SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
  2015. joystick->hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(*joystick->hwdata));
  2016. if (!joystick->hwdata) {
  2017. SDL_free(joystick);
  2018. return false;
  2019. }
  2020. SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, true);
  2021. item->checked_mapping = true;
  2022. if (!PrepareJoystickHwdata(joystick, item, NULL)) {
  2023. goto done; // SDL_SetError will already have been called
  2024. }
  2025. // don't assign `item->hwdata` so it's not in any global state.
  2026. // it is now safe to call LINUX_JoystickClose on this fake joystick.
  2027. if (!joystick->hwdata->has_key[BTN_GAMEPAD]) {
  2028. // Not a gamepad according to the specs.
  2029. goto done;
  2030. }
  2031. // We have a gamepad, start filling out the mappings
  2032. #ifdef DEBUG_GAMEPAD_MAPPING
  2033. SDL_Log("Mapping %s (VID/PID 0x%.4x/0x%.4x)", item->name, SDL_GetJoystickVendor(joystick), SDL_GetJoystickProduct(joystick));
  2034. #endif
  2035. if (joystick->hwdata->has_key[BTN_A]) {
  2036. out->a.kind = EMappingKind_Button;
  2037. out->a.target = joystick->hwdata->key_map[BTN_A];
  2038. #ifdef DEBUG_GAMEPAD_MAPPING
  2039. SDL_Log("Mapped A to button %d (BTN_A)", out->a.target);
  2040. #endif
  2041. }
  2042. if (joystick->hwdata->has_key[BTN_B]) {
  2043. out->b.kind = EMappingKind_Button;
  2044. out->b.target = joystick->hwdata->key_map[BTN_B];
  2045. #ifdef DEBUG_GAMEPAD_MAPPING
  2046. SDL_Log("Mapped B to button %d (BTN_B)", out->b.target);
  2047. #endif
  2048. }
  2049. // Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH
  2050. if (SDL_GetJoystickVendor(joystick) == USB_VENDOR_SONY) {
  2051. if (joystick->hwdata->has_key[BTN_WEST]) {
  2052. out->x.kind = EMappingKind_Button;
  2053. out->x.target = joystick->hwdata->key_map[BTN_WEST];
  2054. #ifdef DEBUG_GAMEPAD_MAPPING
  2055. SDL_Log("Mapped X to button %d (BTN_WEST)", out->x.target);
  2056. #endif
  2057. }
  2058. if (joystick->hwdata->has_key[BTN_NORTH]) {
  2059. out->y.kind = EMappingKind_Button;
  2060. out->y.target = joystick->hwdata->key_map[BTN_NORTH];
  2061. #ifdef DEBUG_GAMEPAD_MAPPING
  2062. SDL_Log("Mapped Y to button %d (BTN_NORTH)", out->y.target);
  2063. #endif
  2064. }
  2065. } else {
  2066. if (joystick->hwdata->has_key[BTN_X]) {
  2067. out->x.kind = EMappingKind_Button;
  2068. out->x.target = joystick->hwdata->key_map[BTN_X];
  2069. #ifdef DEBUG_GAMEPAD_MAPPING
  2070. SDL_Log("Mapped X to button %d (BTN_X)", out->x.target);
  2071. #endif
  2072. }
  2073. if (joystick->hwdata->has_key[BTN_Y]) {
  2074. out->y.kind = EMappingKind_Button;
  2075. out->y.target = joystick->hwdata->key_map[BTN_Y];
  2076. #ifdef DEBUG_GAMEPAD_MAPPING
  2077. SDL_Log("Mapped Y to button %d (BTN_Y)", out->y.target);
  2078. #endif
  2079. }
  2080. }
  2081. if (joystick->hwdata->has_key[BTN_SELECT]) {
  2082. out->back.kind = EMappingKind_Button;
  2083. out->back.target = joystick->hwdata->key_map[BTN_SELECT];
  2084. #ifdef DEBUG_GAMEPAD_MAPPING
  2085. SDL_Log("Mapped BACK to button %d (BTN_SELECT)", out->back.target);
  2086. #endif
  2087. }
  2088. if (joystick->hwdata->has_key[BTN_START]) {
  2089. out->start.kind = EMappingKind_Button;
  2090. out->start.target = joystick->hwdata->key_map[BTN_START];
  2091. #ifdef DEBUG_GAMEPAD_MAPPING
  2092. SDL_Log("Mapped START to button %d (BTN_START)", out->start.target);
  2093. #endif
  2094. }
  2095. if (joystick->hwdata->has_key[BTN_THUMBL]) {
  2096. out->leftstick.kind = EMappingKind_Button;
  2097. out->leftstick.target = joystick->hwdata->key_map[BTN_THUMBL];
  2098. #ifdef DEBUG_GAMEPAD_MAPPING
  2099. SDL_Log("Mapped LEFTSTICK to button %d (BTN_THUMBL)", out->leftstick.target);
  2100. #endif
  2101. }
  2102. if (joystick->hwdata->has_key[BTN_THUMBR]) {
  2103. out->rightstick.kind = EMappingKind_Button;
  2104. out->rightstick.target = joystick->hwdata->key_map[BTN_THUMBR];
  2105. #ifdef DEBUG_GAMEPAD_MAPPING
  2106. SDL_Log("Mapped RIGHTSTICK to button %d (BTN_THUMBR)", out->rightstick.target);
  2107. #endif
  2108. }
  2109. if (joystick->hwdata->has_key[BTN_MODE]) {
  2110. out->guide.kind = EMappingKind_Button;
  2111. out->guide.target = joystick->hwdata->key_map[BTN_MODE];
  2112. #ifdef DEBUG_GAMEPAD_MAPPING
  2113. SDL_Log("Mapped GUIDE to button %d (BTN_MODE)", out->guide.target);
  2114. #endif
  2115. }
  2116. /*
  2117. According to the specs the D-Pad, the shoulder buttons and the triggers
  2118. can be digital, or analog, or both at the same time.
  2119. */
  2120. // Prefer digital shoulder buttons, but settle for digital or analog hat.
  2121. mapped = 0;
  2122. if (joystick->hwdata->has_key[BTN_TL]) {
  2123. out->leftshoulder.kind = EMappingKind_Button;
  2124. out->leftshoulder.target = joystick->hwdata->key_map[BTN_TL];
  2125. mapped |= 0x1;
  2126. #ifdef DEBUG_GAMEPAD_MAPPING
  2127. SDL_Log("Mapped LEFTSHOULDER to button %d (BTN_TL)", out->leftshoulder.target);
  2128. #endif
  2129. }
  2130. if (joystick->hwdata->has_key[BTN_TR]) {
  2131. out->rightshoulder.kind = EMappingKind_Button;
  2132. out->rightshoulder.target = joystick->hwdata->key_map[BTN_TR];
  2133. mapped |= 0x2;
  2134. #ifdef DEBUG_GAMEPAD_MAPPING
  2135. SDL_Log("Mapped RIGHTSHOULDER to button %d (BTN_TR)", out->rightshoulder.target);
  2136. #endif
  2137. }
  2138. if (mapped != 0x3 && joystick->hwdata->has_hat[1]) {
  2139. int hat = joystick->hwdata->hats_indices[1] << 4;
  2140. out->leftshoulder.kind = EMappingKind_Hat;
  2141. out->rightshoulder.kind = EMappingKind_Hat;
  2142. out->leftshoulder.target = hat | 0x4;
  2143. out->rightshoulder.target = hat | 0x2;
  2144. mapped |= 0x3;
  2145. #ifdef DEBUG_GAMEPAD_MAPPING
  2146. SDL_Log("Mapped LEFT+RIGHTSHOULDER to hat 1 (ABS_HAT1X, ABS_HAT1Y)");
  2147. #endif
  2148. }
  2149. if (!(mapped & 0x1) && joystick->hwdata->has_abs[ABS_HAT1Y]) {
  2150. out->leftshoulder.kind = EMappingKind_Axis;
  2151. out->leftshoulder.target = joystick->hwdata->abs_map[ABS_HAT1Y];
  2152. mapped |= 0x1;
  2153. #ifdef DEBUG_GAMEPAD_MAPPING
  2154. SDL_Log("Mapped LEFTSHOULDER to axis %d (ABS_HAT1Y)", out->leftshoulder.target);
  2155. #endif
  2156. }
  2157. if (!(mapped & 0x2) && joystick->hwdata->has_abs[ABS_HAT1X]) {
  2158. out->rightshoulder.kind = EMappingKind_Axis;
  2159. out->rightshoulder.target = joystick->hwdata->abs_map[ABS_HAT1X];
  2160. mapped |= 0x2;
  2161. #ifdef DEBUG_GAMEPAD_MAPPING
  2162. SDL_Log("Mapped RIGHTSHOULDER to axis %d (ABS_HAT1X)", out->rightshoulder.target);
  2163. #endif
  2164. }
  2165. // Prefer analog triggers, but settle for digital hat or buttons.
  2166. mapped = 0;
  2167. /* Unfortunately there are several conventions for how analog triggers
  2168. * are represented as absolute axes:
  2169. *
  2170. * - Linux Gamepad Specification:
  2171. * LT = ABS_HAT2Y, RT = ABS_HAT2X
  2172. * - Android (and therefore many Bluetooth controllers):
  2173. * LT = ABS_BRAKE, RT = ABS_GAS
  2174. * - De facto standard for older Xbox and Playstation controllers:
  2175. * LT = ABS_Z, RT = ABS_RZ
  2176. *
  2177. * We try each one in turn. */
  2178. if (joystick->hwdata->has_abs[ABS_HAT2Y]) {
  2179. // Linux Gamepad Specification
  2180. out->lefttrigger.kind = EMappingKind_Axis;
  2181. out->lefttrigger.target = joystick->hwdata->abs_map[ABS_HAT2Y];
  2182. mapped |= MAPPED_TRIGGER_LEFT;
  2183. #ifdef DEBUG_GAMEPAD_MAPPING
  2184. SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_HAT2Y)", out->lefttrigger.target);
  2185. #endif
  2186. } else if (joystick->hwdata->has_abs[ABS_BRAKE]) {
  2187. // Android convention
  2188. out->lefttrigger.kind = EMappingKind_Axis;
  2189. out->lefttrigger.target = joystick->hwdata->abs_map[ABS_BRAKE];
  2190. mapped |= MAPPED_TRIGGER_LEFT;
  2191. #ifdef DEBUG_GAMEPAD_MAPPING
  2192. SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_BRAKE)", out->lefttrigger.target);
  2193. #endif
  2194. } else if (joystick->hwdata->has_abs[ABS_Z]) {
  2195. // De facto standard for Xbox 360 and Playstation gamepads
  2196. out->lefttrigger.kind = EMappingKind_Axis;
  2197. out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z];
  2198. mapped |= MAPPED_TRIGGER_LEFT;
  2199. #ifdef DEBUG_GAMEPAD_MAPPING
  2200. SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_Z)", out->lefttrigger.target);
  2201. #endif
  2202. }
  2203. if (joystick->hwdata->has_abs[ABS_HAT2X]) {
  2204. // Linux Gamepad Specification
  2205. out->righttrigger.kind = EMappingKind_Axis;
  2206. out->righttrigger.target = joystick->hwdata->abs_map[ABS_HAT2X];
  2207. mapped |= MAPPED_TRIGGER_RIGHT;
  2208. #ifdef DEBUG_GAMEPAD_MAPPING
  2209. SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_HAT2X)", out->righttrigger.target);
  2210. #endif
  2211. } else if (joystick->hwdata->has_abs[ABS_GAS]) {
  2212. // Android convention
  2213. out->righttrigger.kind = EMappingKind_Axis;
  2214. out->righttrigger.target = joystick->hwdata->abs_map[ABS_GAS];
  2215. mapped |= MAPPED_TRIGGER_RIGHT;
  2216. #ifdef DEBUG_GAMEPAD_MAPPING
  2217. SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_GAS)", out->righttrigger.target);
  2218. #endif
  2219. } else if (joystick->hwdata->has_abs[ABS_RZ]) {
  2220. // De facto standard for Xbox 360 and Playstation gamepads
  2221. out->righttrigger.kind = EMappingKind_Axis;
  2222. out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ];
  2223. mapped |= MAPPED_TRIGGER_RIGHT;
  2224. #ifdef DEBUG_GAMEPAD_MAPPING
  2225. SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_RZ)", out->righttrigger.target);
  2226. #endif
  2227. }
  2228. if (mapped != MAPPED_TRIGGER_BOTH && joystick->hwdata->has_hat[2]) {
  2229. int hat = joystick->hwdata->hats_indices[2] << 4;
  2230. out->lefttrigger.kind = EMappingKind_Hat;
  2231. out->righttrigger.kind = EMappingKind_Hat;
  2232. out->lefttrigger.target = hat | 0x4;
  2233. out->righttrigger.target = hat | 0x2;
  2234. mapped |= MAPPED_TRIGGER_BOTH;
  2235. #ifdef DEBUG_GAMEPAD_MAPPING
  2236. SDL_Log("Mapped LEFT+RIGHTTRIGGER to hat 2 (ABS_HAT2X, ABS_HAT2Y)");
  2237. #endif
  2238. }
  2239. if (!(mapped & MAPPED_TRIGGER_LEFT) && joystick->hwdata->has_key[BTN_TL2]) {
  2240. out->lefttrigger.kind = EMappingKind_Button;
  2241. out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
  2242. mapped |= MAPPED_TRIGGER_LEFT;
  2243. #ifdef DEBUG_GAMEPAD_MAPPING
  2244. SDL_Log("Mapped LEFTTRIGGER to button %d (BTN_TL2)", out->lefttrigger.target);
  2245. #endif
  2246. }
  2247. if (!(mapped & MAPPED_TRIGGER_RIGHT) && joystick->hwdata->has_key[BTN_TR2]) {
  2248. out->righttrigger.kind = EMappingKind_Button;
  2249. out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
  2250. mapped |= MAPPED_TRIGGER_RIGHT;
  2251. #ifdef DEBUG_GAMEPAD_MAPPING
  2252. SDL_Log("Mapped RIGHTTRIGGER to button %d (BTN_TR2)", out->righttrigger.target);
  2253. #endif
  2254. }
  2255. // Prefer digital D-Pad buttons, but settle for digital or analog hat.
  2256. mapped = 0;
  2257. if (joystick->hwdata->has_key[BTN_DPAD_UP]) {
  2258. out->dpup.kind = EMappingKind_Button;
  2259. out->dpup.target = joystick->hwdata->key_map[BTN_DPAD_UP];
  2260. mapped |= MAPPED_DPAD_UP;
  2261. #ifdef DEBUG_GAMEPAD_MAPPING
  2262. SDL_Log("Mapped DPUP to button %d (BTN_DPAD_UP)", out->dpup.target);
  2263. #endif
  2264. }
  2265. if (joystick->hwdata->has_key[BTN_DPAD_DOWN]) {
  2266. out->dpdown.kind = EMappingKind_Button;
  2267. out->dpdown.target = joystick->hwdata->key_map[BTN_DPAD_DOWN];
  2268. mapped |= MAPPED_DPAD_DOWN;
  2269. #ifdef DEBUG_GAMEPAD_MAPPING
  2270. SDL_Log("Mapped DPDOWN to button %d (BTN_DPAD_DOWN)", out->dpdown.target);
  2271. #endif
  2272. }
  2273. if (joystick->hwdata->has_key[BTN_DPAD_LEFT]) {
  2274. out->dpleft.kind = EMappingKind_Button;
  2275. out->dpleft.target = joystick->hwdata->key_map[BTN_DPAD_LEFT];
  2276. mapped |= MAPPED_DPAD_LEFT;
  2277. #ifdef DEBUG_GAMEPAD_MAPPING
  2278. SDL_Log("Mapped DPLEFT to button %d (BTN_DPAD_LEFT)", out->dpleft.target);
  2279. #endif
  2280. }
  2281. if (joystick->hwdata->has_key[BTN_DPAD_RIGHT]) {
  2282. out->dpright.kind = EMappingKind_Button;
  2283. out->dpright.target = joystick->hwdata->key_map[BTN_DPAD_RIGHT];
  2284. mapped |= MAPPED_DPAD_RIGHT;
  2285. #ifdef DEBUG_GAMEPAD_MAPPING
  2286. SDL_Log("Mapped DPRIGHT to button %d (BTN_DPAD_RIGHT)", out->dpright.target);
  2287. #endif
  2288. }
  2289. if (mapped != MAPPED_DPAD_ALL) {
  2290. if (joystick->hwdata->has_hat[0]) {
  2291. int hat = joystick->hwdata->hats_indices[0] << 4;
  2292. out->dpleft.kind = EMappingKind_Hat;
  2293. out->dpright.kind = EMappingKind_Hat;
  2294. out->dpup.kind = EMappingKind_Hat;
  2295. out->dpdown.kind = EMappingKind_Hat;
  2296. out->dpleft.target = hat | 0x8;
  2297. out->dpright.target = hat | 0x2;
  2298. out->dpup.target = hat | 0x1;
  2299. out->dpdown.target = hat | 0x4;
  2300. mapped |= MAPPED_DPAD_ALL;
  2301. #ifdef DEBUG_GAMEPAD_MAPPING
  2302. SDL_Log("Mapped DPUP+DOWN+LEFT+RIGHT to hat 0 (ABS_HAT0X, ABS_HAT0Y)");
  2303. #endif
  2304. } else if (joystick->hwdata->has_abs[ABS_HAT0X] && joystick->hwdata->has_abs[ABS_HAT0Y]) {
  2305. out->dpleft.kind = EMappingKind_Axis;
  2306. out->dpright.kind = EMappingKind_Axis;
  2307. out->dpup.kind = EMappingKind_Axis;
  2308. out->dpdown.kind = EMappingKind_Axis;
  2309. out->dpleft.target = joystick->hwdata->abs_map[ABS_HAT0X];
  2310. out->dpright.target = joystick->hwdata->abs_map[ABS_HAT0X];
  2311. out->dpup.target = joystick->hwdata->abs_map[ABS_HAT0Y];
  2312. out->dpdown.target = joystick->hwdata->abs_map[ABS_HAT0Y];
  2313. mapped |= MAPPED_DPAD_ALL;
  2314. #ifdef DEBUG_GAMEPAD_MAPPING
  2315. SDL_Log("Mapped DPUP+DOWN to axis %d (ABS_HAT0Y)", out->dpup.target);
  2316. SDL_Log("Mapped DPLEFT+RIGHT to axis %d (ABS_HAT0X)", out->dpleft.target);
  2317. #endif
  2318. } else if (item->driver && SDL_strcmp(item->driver, "xpad") == 0) {
  2319. // xpad will sometimes map the D-Pad as BTN_TRIGGER_HAPPY1 - BTN_TRIGGER_HAPPY4
  2320. if (joystick->hwdata->has_key[BTN_TRIGGER_HAPPY1] &&
  2321. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY2] &&
  2322. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY3] &&
  2323. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY4]) {
  2324. out->dpleft.kind = EMappingKind_Button;
  2325. out->dpright.kind = EMappingKind_Button;
  2326. out->dpup.kind = EMappingKind_Button;
  2327. out->dpdown.kind = EMappingKind_Button;
  2328. out->dpleft.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY1];
  2329. out->dpright.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY2];
  2330. out->dpup.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY3];
  2331. out->dpdown.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY4];
  2332. #ifdef DEBUG_GAMEPAD_MAPPING
  2333. SDL_Log("Mapped DPLEFT to button %d (BTN_TRIGGER_HAPPY1)", out->dpleft.target);
  2334. SDL_Log("Mapped DPRIGHT to button %d (BTN_TRIGGER_HAPPY2)", out->dpright.target);
  2335. SDL_Log("Mapped DPUP to button %d (BTN_TRIGGER_HAPPY3)", out->dpup.target);
  2336. SDL_Log("Mapped DPDOWN to button %d (BTN_TRIGGER_HAPPY4)", out->dpdown.target);
  2337. #endif
  2338. }
  2339. }
  2340. }
  2341. if (joystick->hwdata->has_abs[ABS_X] && joystick->hwdata->has_abs[ABS_Y]) {
  2342. out->leftx.kind = EMappingKind_Axis;
  2343. out->lefty.kind = EMappingKind_Axis;
  2344. out->leftx.target = joystick->hwdata->abs_map[ABS_X];
  2345. out->lefty.target = joystick->hwdata->abs_map[ABS_Y];
  2346. #ifdef DEBUG_GAMEPAD_MAPPING
  2347. SDL_Log("Mapped LEFTX to axis %d (ABS_X)", out->leftx.target);
  2348. SDL_Log("Mapped LEFTY to axis %d (ABS_Y)", out->lefty.target);
  2349. #endif
  2350. }
  2351. /* The Linux Gamepad Specification uses the RX and RY axes,
  2352. * originally intended to represent X and Y rotation, as a second
  2353. * joystick. This is common for USB gamepads, and also many Bluetooth
  2354. * gamepads, particularly older ones.
  2355. *
  2356. * The Android mapping convention used by many Bluetooth controllers
  2357. * instead uses the Z axis as a secondary X axis, and the RZ axis as
  2358. * a secondary Y axis. */
  2359. if (joystick->hwdata->has_abs[ABS_RX] && joystick->hwdata->has_abs[ABS_RY]) {
  2360. // Linux Gamepad Specification, Xbox 360, Playstation etc.
  2361. out->rightx.kind = EMappingKind_Axis;
  2362. out->righty.kind = EMappingKind_Axis;
  2363. out->rightx.target = joystick->hwdata->abs_map[ABS_RX];
  2364. out->righty.target = joystick->hwdata->abs_map[ABS_RY];
  2365. #ifdef DEBUG_GAMEPAD_MAPPING
  2366. SDL_Log("Mapped RIGHTX to axis %d (ABS_RX)", out->rightx.target);
  2367. SDL_Log("Mapped RIGHTY to axis %d (ABS_RY)", out->righty.target);
  2368. #endif
  2369. } else if (joystick->hwdata->has_abs[ABS_Z] && joystick->hwdata->has_abs[ABS_RZ]) {
  2370. // Android convention
  2371. out->rightx.kind = EMappingKind_Axis;
  2372. out->righty.kind = EMappingKind_Axis;
  2373. out->rightx.target = joystick->hwdata->abs_map[ABS_Z];
  2374. out->righty.target = joystick->hwdata->abs_map[ABS_RZ];
  2375. #ifdef DEBUG_GAMEPAD_MAPPING
  2376. SDL_Log("Mapped RIGHTX to axis %d (ABS_Z)", out->rightx.target);
  2377. SDL_Log("Mapped RIGHTY to axis %d (ABS_RZ)", out->righty.target);
  2378. #endif
  2379. }
  2380. mapped = 0;
  2381. if (joystick->hwdata->has_key[BTN_GRIPR]) {
  2382. out->right_paddle1.kind = EMappingKind_Button;
  2383. out->right_paddle1.target = joystick->hwdata->key_map[BTN_GRIPR];
  2384. mapped |= MAPPED_RIGHT_PADDLE1;
  2385. #ifdef DEBUG_GAMEPAD_MAPPING
  2386. SDL_Log("Mapped RIGHT_PADDLE1 to button %d (BTN_GRIPR)", out->right_paddle1.target);
  2387. #endif
  2388. }
  2389. if (joystick->hwdata->has_key[BTN_GRIPL]) {
  2390. out->left_paddle1.kind = EMappingKind_Button;
  2391. out->left_paddle1.target = joystick->hwdata->key_map[BTN_GRIPL];
  2392. mapped |= MAPPED_LEFT_PADDLE1;
  2393. #ifdef DEBUG_GAMEPAD_MAPPING
  2394. SDL_Log("Mapped LEFT_PADDLE1 to button %d (BTN_GRIPL)", out->left_paddle1.target);
  2395. #endif
  2396. }
  2397. if (joystick->hwdata->has_key[BTN_GRIPR2]) {
  2398. out->right_paddle2.kind = EMappingKind_Button;
  2399. out->right_paddle2.target = joystick->hwdata->key_map[BTN_GRIPR2];
  2400. mapped |= MAPPED_RIGHT_PADDLE2;
  2401. #ifdef DEBUG_GAMEPAD_MAPPING
  2402. SDL_Log("Mapped RIGHT_PADDLE2 to button %d (BTN_GRIPR)", out->right_paddle2.target);
  2403. #endif
  2404. }
  2405. if (joystick->hwdata->has_key[BTN_GRIPL2]) {
  2406. out->left_paddle2.kind = EMappingKind_Button;
  2407. out->left_paddle2.target = joystick->hwdata->key_map[BTN_GRIPL2];
  2408. mapped |= MAPPED_LEFT_PADDLE2;
  2409. #ifdef DEBUG_GAMEPAD_MAPPING
  2410. SDL_Log("Mapped LEFT_PADDLE2 to button %d (BTN_GRIPL2)", out->left_paddle2.target);
  2411. #endif
  2412. }
  2413. if (mapped != MAPPED_PADDLE_ALL && SDL_GetJoystickVendor(joystick) == USB_VENDOR_MICROSOFT) {
  2414. // The Xbox Elite controllers have the paddles as BTN_TRIGGER_HAPPY5 - BTN_TRIGGER_HAPPY8
  2415. // in older drivers
  2416. if (joystick->hwdata->has_key[BTN_TRIGGER_HAPPY5] &&
  2417. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY6] &&
  2418. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY7] &&
  2419. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY8]) {
  2420. out->right_paddle1.kind = EMappingKind_Button;
  2421. out->right_paddle1.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY5];
  2422. out->left_paddle1.kind = EMappingKind_Button;
  2423. out->left_paddle1.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY7];
  2424. out->right_paddle2.kind = EMappingKind_Button;
  2425. out->right_paddle2.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY6];
  2426. out->left_paddle2.kind = EMappingKind_Button;
  2427. out->left_paddle2.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY8];
  2428. mapped = MAPPED_PADDLE_ALL;
  2429. #ifdef DEBUG_GAMEPAD_MAPPING
  2430. SDL_Log("Mapped RIGHT_PADDLE1 to button %d (BTN_TRIGGER_HAPPY5)", out->right_paddle1.target);
  2431. SDL_Log("Mapped LEFT_PADDLE1 to button %d (BTN_TRIGGER_HAPPY7)", out->left_paddle1.target);
  2432. SDL_Log("Mapped RIGHT_PADDLE2 to button %d (BTN_TRIGGER_HAPPY6)", out->right_paddle2.target);
  2433. SDL_Log("Mapped LEFT_PADDLE2 to button %d (BTN_TRIGGER_HAPPY8)", out->left_paddle2.target);
  2434. #endif
  2435. }
  2436. }
  2437. // Xbox Series controllers have the Share button as KEY_RECORD
  2438. if (joystick->hwdata->has_key[KEY_RECORD]) {
  2439. out->misc1.kind = EMappingKind_Button;
  2440. out->misc1.target = joystick->hwdata->key_map[KEY_RECORD];
  2441. #ifdef DEBUG_GAMEPAD_MAPPING
  2442. SDL_Log("Mapped MISC1 to button %d (KEY_RECORD)", out->misc1.target);
  2443. #endif
  2444. }
  2445. // Cache the mapping for later
  2446. item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping));
  2447. if (item->mapping) {
  2448. SDL_memcpy(item->mapping, out, sizeof(*out));
  2449. }
  2450. #ifdef DEBUG_GAMEPAD_MAPPING
  2451. SDL_Log("Generated mapping for device %d", device_index);
  2452. #endif
  2453. result = true;
  2454. done:
  2455. LINUX_JoystickClose(joystick);
  2456. SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, false);
  2457. SDL_free(joystick);
  2458. return result;
  2459. }
  2460. SDL_JoystickDriver SDL_LINUX_JoystickDriver = {
  2461. LINUX_JoystickInit,
  2462. LINUX_JoystickGetCount,
  2463. LINUX_JoystickDetect,
  2464. LINUX_JoystickIsDevicePresent,
  2465. LINUX_JoystickGetDeviceName,
  2466. LINUX_JoystickGetDevicePath,
  2467. LINUX_JoystickGetDeviceSteamVirtualGamepadSlot,
  2468. LINUX_JoystickGetDevicePlayerIndex,
  2469. LINUX_JoystickSetDevicePlayerIndex,
  2470. LINUX_JoystickGetDeviceGUID,
  2471. LINUX_JoystickGetDeviceInstanceID,
  2472. LINUX_JoystickOpen,
  2473. LINUX_JoystickRumble,
  2474. LINUX_JoystickRumbleTriggers,
  2475. LINUX_JoystickSetLED,
  2476. LINUX_JoystickSendEffect,
  2477. LINUX_JoystickSetSensorsEnabled,
  2478. LINUX_JoystickUpdate,
  2479. LINUX_JoystickClose,
  2480. LINUX_JoystickQuit,
  2481. LINUX_JoystickGetGamepadMapping
  2482. };
  2483. #endif // SDL_JOYSTICK_LINUX