SDL_sysjoystick.c 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
  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. #endif
  31. #include <sys/ioctl.h>
  32. #include <unistd.h>
  33. #include <dirent.h>
  34. #include <linux/joystick.h>
  35. #include "SDL_hints.h"
  36. #include "SDL_joystick.h"
  37. #include "SDL_log.h"
  38. #include "SDL_endian.h"
  39. #include "SDL_timer.h"
  40. #include "../../events/SDL_events_c.h"
  41. #include "../SDL_sysjoystick.h"
  42. #include "../SDL_joystick_c.h"
  43. #include "../steam/SDL_steamcontroller.h"
  44. #include "SDL_sysjoystick_c.h"
  45. #include "../hidapi/SDL_hidapijoystick_c.h"
  46. /* This isn't defined in older Linux kernel headers */
  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_TRIGGER_HAPPY
  69. #define BTN_TRIGGER_HAPPY 0x2c0
  70. #define BTN_TRIGGER_HAPPY1 0x2c0
  71. #define BTN_TRIGGER_HAPPY2 0x2c1
  72. #define BTN_TRIGGER_HAPPY3 0x2c2
  73. #define BTN_TRIGGER_HAPPY4 0x2c3
  74. #define BTN_TRIGGER_HAPPY5 0x2c4
  75. #define BTN_TRIGGER_HAPPY6 0x2c5
  76. #define BTN_TRIGGER_HAPPY7 0x2c6
  77. #define BTN_TRIGGER_HAPPY8 0x2c7
  78. #define BTN_TRIGGER_HAPPY9 0x2c8
  79. #define BTN_TRIGGER_HAPPY10 0x2c9
  80. #define BTN_TRIGGER_HAPPY11 0x2ca
  81. #define BTN_TRIGGER_HAPPY12 0x2cb
  82. #define BTN_TRIGGER_HAPPY13 0x2cc
  83. #define BTN_TRIGGER_HAPPY14 0x2cd
  84. #define BTN_TRIGGER_HAPPY15 0x2ce
  85. #define BTN_TRIGGER_HAPPY16 0x2cf
  86. #define BTN_TRIGGER_HAPPY17 0x2d0
  87. #define BTN_TRIGGER_HAPPY18 0x2d1
  88. #define BTN_TRIGGER_HAPPY19 0x2d2
  89. #define BTN_TRIGGER_HAPPY20 0x2d3
  90. #define BTN_TRIGGER_HAPPY21 0x2d4
  91. #define BTN_TRIGGER_HAPPY22 0x2d5
  92. #define BTN_TRIGGER_HAPPY23 0x2d6
  93. #define BTN_TRIGGER_HAPPY24 0x2d7
  94. #define BTN_TRIGGER_HAPPY25 0x2d8
  95. #define BTN_TRIGGER_HAPPY26 0x2d9
  96. #define BTN_TRIGGER_HAPPY27 0x2da
  97. #define BTN_TRIGGER_HAPPY28 0x2db
  98. #define BTN_TRIGGER_HAPPY29 0x2dc
  99. #define BTN_TRIGGER_HAPPY30 0x2dd
  100. #define BTN_TRIGGER_HAPPY31 0x2de
  101. #define BTN_TRIGGER_HAPPY32 0x2df
  102. #define BTN_TRIGGER_HAPPY33 0x2e0
  103. #define BTN_TRIGGER_HAPPY34 0x2e1
  104. #define BTN_TRIGGER_HAPPY35 0x2e2
  105. #define BTN_TRIGGER_HAPPY36 0x2e3
  106. #define BTN_TRIGGER_HAPPY37 0x2e4
  107. #define BTN_TRIGGER_HAPPY38 0x2e5
  108. #define BTN_TRIGGER_HAPPY39 0x2e6
  109. #define BTN_TRIGGER_HAPPY40 0x2e7
  110. #endif
  111. #include "../../core/linux/SDL_evdev_capabilities.h"
  112. #include "../../core/linux/SDL_udev.h"
  113. #include "../../core/linux/SDL_sandbox.h"
  114. #if 0
  115. #define DEBUG_INPUT_EVENTS 1
  116. #endif
  117. #if 0
  118. #define DEBUG_GAMEPAD_MAPPING 1
  119. #endif
  120. typedef enum
  121. {
  122. ENUMERATION_UNSET,
  123. ENUMERATION_LIBUDEV,
  124. ENUMERATION_FALLBACK
  125. } EnumerationMethod;
  126. static EnumerationMethod enumeration_method = ENUMERATION_UNSET;
  127. static SDL_bool IsJoystickJSNode(const char *node);
  128. static int MaybeAddDevice(const char *path);
  129. static int MaybeRemoveDevice(const char *path);
  130. /* A linked list of available joysticks */
  131. typedef struct SDL_joylist_item
  132. {
  133. SDL_JoystickID device_instance;
  134. char *path; /* "/dev/input/event2" or whatever */
  135. char *name; /* "SideWinder 3D Pro" or whatever */
  136. SDL_JoystickGUID guid;
  137. dev_t devnum;
  138. struct joystick_hwdata *hwdata;
  139. struct SDL_joylist_item *next;
  140. /* Steam Controller support */
  141. SDL_bool m_bSteamController;
  142. SDL_bool checked_mapping;
  143. SDL_GamepadMapping *mapping;
  144. } SDL_joylist_item;
  145. static SDL_bool SDL_classic_joysticks = SDL_FALSE;
  146. static SDL_joylist_item *SDL_joylist = NULL;
  147. static SDL_joylist_item *SDL_joylist_tail = NULL;
  148. static int numjoysticks = 0;
  149. static int inotify_fd = -1;
  150. static Uint32 last_joy_detect_time;
  151. static time_t last_input_dir_mtime;
  152. static void FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
  153. {
  154. if (inpid->vendor == 0x045e && inpid->product == 0x0b05 && inpid->version == 0x0903) {
  155. /* This is a Microsoft Xbox One Elite Series 2 controller */
  156. unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
  157. /* The first version of the firmware duplicated all the inputs */
  158. if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
  159. test_bit(0x2c0, keybit)) {
  160. /* Change the version to 0x0902, so we can map it differently */
  161. inpid->version = 0x0902;
  162. }
  163. }
  164. /* For Atari vcs modern and classic controllers have the version reflecting
  165. * firmware version, but the mapping stays stable so ignore
  166. * version information */
  167. if (inpid->vendor == 0x3250 && (inpid->product == 0x1001 || inpid->product == 0x1002)) {
  168. inpid->version = 0;
  169. }
  170. }
  171. #ifdef SDL_JOYSTICK_HIDAPI
  172. static SDL_bool IsVirtualJoystick(Uint16 vendor, Uint16 product, Uint16 version, const char *name)
  173. {
  174. if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_S && version == 0 &&
  175. SDL_strcmp(name, "Xbox One S Controller") == 0) {
  176. /* This is the virtual device created by the xow driver */
  177. return SDL_TRUE;
  178. }
  179. return SDL_FALSE;
  180. }
  181. #endif /* SDL_JOYSTICK_HIDAPI */
  182. static int GuessIsJoystick(int fd)
  183. {
  184. unsigned long evbit[NBITS(EV_MAX)] = { 0 };
  185. unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
  186. unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
  187. unsigned long relbit[NBITS(REL_MAX)] = { 0 };
  188. int devclass;
  189. if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
  190. (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
  191. (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) < 0) ||
  192. (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) {
  193. return 0;
  194. }
  195. devclass = SDL_EVDEV_GuessDeviceClass(evbit, absbit, keybit, relbit);
  196. if (devclass & SDL_UDEV_DEVICE_JOYSTICK) {
  197. return 1;
  198. }
  199. return 0;
  200. }
  201. static int IsJoystick(const char *path, int fd, char **name_return, SDL_JoystickGUID *guid)
  202. {
  203. struct input_id inpid;
  204. char *name;
  205. char product_string[128];
  206. if (ioctl(fd, JSIOCGNAME(sizeof(product_string)), product_string) >= 0) {
  207. SDL_zero(inpid);
  208. #if SDL_USE_LIBUDEV
  209. SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version);
  210. #endif
  211. } else {
  212. /* When udev is enabled we only get joystick devices here, so there's no need to test them */
  213. if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) {
  214. return 0;
  215. }
  216. if (ioctl(fd, EVIOCGID, &inpid) < 0) {
  217. return 0;
  218. }
  219. if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) {
  220. return 0;
  221. }
  222. }
  223. name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string);
  224. if (name == NULL) {
  225. return 0;
  226. }
  227. #ifdef SDL_JOYSTICK_HIDAPI
  228. if (!IsVirtualJoystick(inpid.vendor, inpid.product, inpid.version, name) &&
  229. HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version, name)) {
  230. /* The HIDAPI driver is taking care of this device */
  231. SDL_free(name);
  232. return 0;
  233. }
  234. #endif
  235. FixupDeviceInfoForMapping(fd, &inpid);
  236. #ifdef DEBUG_JOYSTICK
  237. SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
  238. #endif
  239. *guid = SDL_CreateJoystickGUID(inpid.bustype, inpid.vendor, inpid.product, inpid.version, name, 0, 0);
  240. if (SDL_ShouldIgnoreJoystick(name, *guid)) {
  241. SDL_free(name);
  242. return 0;
  243. }
  244. *name_return = name;
  245. return 1;
  246. }
  247. #if SDL_USE_LIBUDEV
  248. static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
  249. {
  250. if (devpath == NULL) {
  251. return;
  252. }
  253. switch (udev_type) {
  254. case SDL_UDEV_DEVICEADDED:
  255. if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
  256. return;
  257. }
  258. if (SDL_classic_joysticks) {
  259. if (!IsJoystickJSNode(devpath)) {
  260. return;
  261. }
  262. } else {
  263. if (IsJoystickJSNode(devpath)) {
  264. return;
  265. }
  266. }
  267. /* Wait a bit for the hidraw udev node to initialize */
  268. SDL_Delay(10);
  269. MaybeAddDevice(devpath);
  270. break;
  271. case SDL_UDEV_DEVICEREMOVED:
  272. MaybeRemoveDevice(devpath);
  273. break;
  274. default:
  275. break;
  276. }
  277. }
  278. #endif /* SDL_USE_LIBUDEV */
  279. static void FreeJoylistItem(SDL_joylist_item *item)
  280. {
  281. SDL_free(item->mapping);
  282. SDL_free(item->path);
  283. SDL_free(item->name);
  284. SDL_free(item);
  285. }
  286. static int MaybeAddDevice(const char *path)
  287. {
  288. struct stat sb;
  289. int fd = -1;
  290. int isstick = 0;
  291. char *name = NULL;
  292. SDL_JoystickGUID guid;
  293. SDL_joylist_item *item;
  294. if (path == NULL) {
  295. return -1;
  296. }
  297. if (stat(path, &sb) == -1) {
  298. return -1;
  299. }
  300. /* Check to make sure it's not already in list. */
  301. for (item = SDL_joylist; item != NULL; item = item->next) {
  302. if (sb.st_rdev == item->devnum) {
  303. return -1; /* already have this one */
  304. }
  305. }
  306. fd = open(path, O_RDONLY | O_CLOEXEC, 0);
  307. if (fd < 0) {
  308. return -1;
  309. }
  310. #ifdef DEBUG_INPUT_EVENTS
  311. SDL_Log("Checking %s\n", path);
  312. #endif
  313. isstick = IsJoystick(path, fd, &name, &guid);
  314. close(fd);
  315. if (!isstick) {
  316. return -1;
  317. }
  318. item = (SDL_joylist_item *)SDL_calloc(1, sizeof(SDL_joylist_item));
  319. if (item == NULL) {
  320. SDL_free(name);
  321. return -1;
  322. }
  323. item->devnum = sb.st_rdev;
  324. item->path = SDL_strdup(path);
  325. item->name = name;
  326. item->guid = guid;
  327. if ((item->path == NULL) || (item->name == NULL)) {
  328. FreeJoylistItem(item);
  329. return -1;
  330. }
  331. item->device_instance = SDL_GetNextJoystickInstanceID();
  332. if (SDL_joylist_tail == NULL) {
  333. SDL_joylist = SDL_joylist_tail = item;
  334. } else {
  335. SDL_joylist_tail->next = item;
  336. SDL_joylist_tail = item;
  337. }
  338. /* Need to increment the joystick count before we post the event */
  339. ++numjoysticks;
  340. SDL_PrivateJoystickAdded(item->device_instance);
  341. return numjoysticks;
  342. }
  343. static void RemoveJoylistItem(SDL_joylist_item *item, SDL_joylist_item *prev)
  344. {
  345. if (item->hwdata) {
  346. item->hwdata->item = NULL;
  347. }
  348. if (prev != NULL) {
  349. prev->next = item->next;
  350. } else {
  351. SDL_assert(SDL_joylist == item);
  352. SDL_joylist = item->next;
  353. }
  354. if (item == SDL_joylist_tail) {
  355. SDL_joylist_tail = prev;
  356. }
  357. /* Need to decrement the joystick count before we post the event */
  358. --numjoysticks;
  359. SDL_PrivateJoystickRemoved(item->device_instance);
  360. FreeJoylistItem(item);
  361. }
  362. static int MaybeRemoveDevice(const char *path)
  363. {
  364. SDL_joylist_item *item;
  365. SDL_joylist_item *prev = NULL;
  366. if (path == NULL) {
  367. return -1;
  368. }
  369. for (item = SDL_joylist; item != NULL; item = item->next) {
  370. /* found it, remove it. */
  371. if (SDL_strcmp(path, item->path) == 0) {
  372. const int retval = item->device_instance;
  373. RemoveJoylistItem(item, prev);
  374. return retval;
  375. }
  376. prev = item;
  377. }
  378. return -1;
  379. }
  380. static void HandlePendingRemovals(void)
  381. {
  382. SDL_joylist_item *prev = NULL;
  383. SDL_joylist_item *item = SDL_joylist;
  384. while (item != NULL) {
  385. if (item->hwdata && item->hwdata->gone) {
  386. RemoveJoylistItem(item, prev);
  387. if (prev != NULL) {
  388. item = prev->next;
  389. } else {
  390. item = SDL_joylist;
  391. }
  392. } else {
  393. prev = item;
  394. item = item->next;
  395. }
  396. }
  397. }
  398. static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance)
  399. {
  400. SDL_joylist_item *item;
  401. item = (SDL_joylist_item *)SDL_calloc(1, sizeof(SDL_joylist_item));
  402. if (item == NULL) {
  403. return SDL_FALSE;
  404. }
  405. item->path = SDL_strdup("");
  406. item->name = SDL_strdup(name);
  407. item->guid = guid;
  408. item->m_bSteamController = SDL_TRUE;
  409. if ((item->path == NULL) || (item->name == NULL)) {
  410. FreeJoylistItem(item);
  411. return SDL_FALSE;
  412. }
  413. *device_instance = item->device_instance = SDL_GetNextJoystickInstanceID();
  414. if (SDL_joylist_tail == NULL) {
  415. SDL_joylist = SDL_joylist_tail = item;
  416. } else {
  417. SDL_joylist_tail->next = item;
  418. SDL_joylist_tail = item;
  419. }
  420. /* Need to increment the joystick count before we post the event */
  421. ++numjoysticks;
  422. SDL_PrivateJoystickAdded(item->device_instance);
  423. return SDL_TRUE;
  424. }
  425. static void SteamControllerDisconnectedCallback(int device_instance)
  426. {
  427. SDL_joylist_item *item;
  428. SDL_joylist_item *prev = NULL;
  429. for (item = SDL_joylist; item != NULL; item = item->next) {
  430. /* found it, remove it. */
  431. if (item->device_instance == device_instance) {
  432. RemoveJoylistItem(item, prev);
  433. return;
  434. }
  435. prev = item;
  436. }
  437. }
  438. static int StrHasPrefix(const char *string, const char *prefix)
  439. {
  440. return SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0;
  441. }
  442. static int StrIsInteger(const char *string)
  443. {
  444. const char *p;
  445. if (*string == '\0') {
  446. return 0;
  447. }
  448. for (p = string; *p != '\0'; p++) {
  449. if (*p < '0' || *p > '9') {
  450. return 0;
  451. }
  452. }
  453. return 1;
  454. }
  455. static SDL_bool IsJoystickJSNode(const char *node)
  456. {
  457. const char *last_slash = SDL_strrchr(node, '/');
  458. if (last_slash) {
  459. node = last_slash + 1;
  460. }
  461. return StrHasPrefix(node, "js") && StrIsInteger(node + 2);
  462. }
  463. static SDL_bool IsJoystickEventNode(const char *node)
  464. {
  465. const char *last_slash = SDL_strrchr(node, '/');
  466. if (last_slash) {
  467. node = last_slash + 1;
  468. }
  469. return StrHasPrefix(node, "event") && StrIsInteger(node + 5);
  470. }
  471. static SDL_bool IsJoystickDeviceNode(const char *node)
  472. {
  473. if (SDL_classic_joysticks) {
  474. return IsJoystickJSNode(node);
  475. } else {
  476. return IsJoystickEventNode(node);
  477. }
  478. }
  479. #ifdef HAVE_INOTIFY
  480. #ifdef HAVE_INOTIFY_INIT1
  481. static int SDL_inotify_init1(void)
  482. {
  483. return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
  484. }
  485. #else
  486. static int SDL_inotify_init1(void)
  487. {
  488. int fd = inotify_init();
  489. if (fd < 0) {
  490. return -1;
  491. }
  492. fcntl(fd, F_SETFL, O_NONBLOCK);
  493. fcntl(fd, F_SETFD, FD_CLOEXEC);
  494. return fd;
  495. }
  496. #endif
  497. static void LINUX_InotifyJoystickDetect(void)
  498. {
  499. union
  500. {
  501. struct inotify_event event;
  502. char storage[4096];
  503. char enough_for_inotify[sizeof(struct inotify_event) + NAME_MAX + 1];
  504. } buf;
  505. ssize_t bytes;
  506. size_t remain = 0;
  507. size_t len;
  508. char path[PATH_MAX];
  509. bytes = read(inotify_fd, &buf, sizeof(buf));
  510. if (bytes > 0) {
  511. remain = (size_t)bytes;
  512. }
  513. while (remain > 0) {
  514. if (buf.event.len > 0) {
  515. if (IsJoystickDeviceNode(buf.event.name)) {
  516. (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", buf.event.name);
  517. if (buf.event.mask & (IN_CREATE | IN_MOVED_TO | IN_ATTRIB)) {
  518. MaybeAddDevice(path);
  519. } else if (buf.event.mask & (IN_DELETE | IN_MOVED_FROM)) {
  520. MaybeRemoveDevice(path);
  521. }
  522. }
  523. }
  524. len = sizeof(struct inotify_event) + buf.event.len;
  525. remain -= len;
  526. if (remain != 0) {
  527. SDL_memmove(&buf.storage[0], &buf.storage[len], remain);
  528. }
  529. }
  530. }
  531. #endif /* HAVE_INOTIFY */
  532. static int get_event_joystick_index(int event)
  533. {
  534. int joystick_index = -1;
  535. int i, count;
  536. struct dirent **entries = NULL;
  537. char path[PATH_MAX];
  538. (void)SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event);
  539. count = scandir(path, &entries, NULL, alphasort);
  540. for (i = 0; i < count; ++i) {
  541. if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) {
  542. joystick_index = SDL_atoi(entries[i]->d_name + 2);
  543. }
  544. free(entries[i]); /* This should NOT be SDL_free() */
  545. }
  546. free(entries); /* This should NOT be SDL_free() */
  547. return joystick_index;
  548. }
  549. /* Detect devices by reading /dev/input. In the inotify code path we
  550. * have to do this the first time, to detect devices that already existed
  551. * before we started; in the non-inotify code path we do this repeatedly
  552. * (polling). */
  553. static int filter_entries(const struct dirent *entry)
  554. {
  555. return IsJoystickDeviceNode(entry->d_name);
  556. }
  557. static int sort_entries(const void *_a, const void *_b)
  558. {
  559. const struct dirent **a = (const struct dirent **)_a;
  560. const struct dirent **b = (const struct dirent **)_b;
  561. int numA, numB;
  562. int offset;
  563. if (SDL_classic_joysticks) {
  564. offset = 2; /* strlen("js") */
  565. numA = SDL_atoi((*a)->d_name + offset);
  566. numB = SDL_atoi((*b)->d_name + offset);
  567. } else {
  568. offset = 5; /* strlen("event") */
  569. numA = SDL_atoi((*a)->d_name + offset);
  570. numB = SDL_atoi((*b)->d_name + offset);
  571. /* See if we can get the joystick ordering */
  572. {
  573. int jsA = get_event_joystick_index(numA);
  574. int jsB = get_event_joystick_index(numB);
  575. if (jsA >= 0 && jsB >= 0) {
  576. numA = jsA;
  577. numB = jsB;
  578. } else if (jsA >= 0) {
  579. return -1;
  580. } else if (jsB >= 0) {
  581. return 1;
  582. }
  583. }
  584. }
  585. return numA - numB;
  586. }
  587. static void LINUX_FallbackJoystickDetect(void)
  588. {
  589. const Uint32 SDL_JOY_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */
  590. Uint32 now = SDL_GetTicks();
  591. if (!last_joy_detect_time || SDL_TICKS_PASSED(now, last_joy_detect_time + SDL_JOY_DETECT_INTERVAL_MS)) {
  592. struct stat sb;
  593. /* Opening input devices can generate synchronous device I/O, so avoid it if we can */
  594. if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
  595. int i, count;
  596. struct dirent **entries = NULL;
  597. char path[PATH_MAX];
  598. count = scandir("/dev/input", &entries, filter_entries, NULL);
  599. if (count > 1) {
  600. qsort(entries, count, sizeof(*entries), sort_entries);
  601. }
  602. for (i = 0; i < count; ++i) {
  603. (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name);
  604. MaybeAddDevice(path);
  605. free(entries[i]); /* This should NOT be SDL_free() */
  606. }
  607. free(entries); /* This should NOT be SDL_free() */
  608. last_input_dir_mtime = sb.st_mtime;
  609. }
  610. last_joy_detect_time = now;
  611. }
  612. }
  613. static void LINUX_JoystickDetect(void)
  614. {
  615. #if SDL_USE_LIBUDEV
  616. if (enumeration_method == ENUMERATION_LIBUDEV) {
  617. SDL_UDEV_Poll();
  618. } else
  619. #endif
  620. #ifdef HAVE_INOTIFY
  621. if (inotify_fd >= 0 && last_joy_detect_time != 0) {
  622. LINUX_InotifyJoystickDetect();
  623. } else
  624. #endif
  625. {
  626. LINUX_FallbackJoystickDetect();
  627. }
  628. HandlePendingRemovals();
  629. SDL_UpdateSteamControllers();
  630. }
  631. static int LINUX_JoystickInit(void)
  632. {
  633. const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE);
  634. SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
  635. enumeration_method = ENUMERATION_UNSET;
  636. /* First see if the user specified one or more joysticks to use */
  637. if (devices != NULL) {
  638. char *envcopy, *envpath, *delim;
  639. envcopy = SDL_strdup(devices);
  640. envpath = envcopy;
  641. while (envpath != NULL) {
  642. delim = SDL_strchr(envpath, ':');
  643. if (delim != NULL) {
  644. *delim++ = '\0';
  645. }
  646. MaybeAddDevice(envpath);
  647. envpath = delim;
  648. }
  649. SDL_free(envcopy);
  650. }
  651. SDL_InitSteamControllers(SteamControllerConnectedCallback,
  652. SteamControllerDisconnectedCallback);
  653. /* Force immediate joystick detection if using fallback */
  654. last_joy_detect_time = 0;
  655. last_input_dir_mtime = 0;
  656. /* Manually scan first, since we sort by device number and udev doesn't */
  657. LINUX_JoystickDetect();
  658. #if SDL_USE_LIBUDEV
  659. if (enumeration_method == ENUMERATION_UNSET) {
  660. if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
  661. SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
  662. "udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
  663. enumeration_method = ENUMERATION_FALLBACK;
  664. } else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
  665. SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
  666. "Container detected, disabling udev integration");
  667. enumeration_method = ENUMERATION_FALLBACK;
  668. } else {
  669. SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
  670. "Using udev for joystick device discovery");
  671. enumeration_method = ENUMERATION_LIBUDEV;
  672. }
  673. }
  674. if (enumeration_method == ENUMERATION_LIBUDEV) {
  675. if (SDL_UDEV_Init() < 0) {
  676. return SDL_SetError("Could not initialize UDEV");
  677. }
  678. /* Set up the udev callback */
  679. if (SDL_UDEV_AddCallback(joystick_udev_callback) < 0) {
  680. SDL_UDEV_Quit();
  681. return SDL_SetError("Could not set up joystick <-> udev callback");
  682. }
  683. /* Force a scan to build the initial device list */
  684. SDL_UDEV_Scan();
  685. } else
  686. #endif
  687. {
  688. #if defined(HAVE_INOTIFY)
  689. inotify_fd = SDL_inotify_init1();
  690. if (inotify_fd < 0) {
  691. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
  692. "Unable to initialize inotify, falling back to polling: %s",
  693. strerror(errno));
  694. } else {
  695. /* We need to watch for attribute changes in addition to
  696. * creation, because when a device is first created, it has
  697. * permissions that we can't read. When udev chmods it to
  698. * something that we maybe *can* read, we'll get an
  699. * IN_ATTRIB event to tell us. */
  700. if (inotify_add_watch(inotify_fd, "/dev/input",
  701. IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) {
  702. close(inotify_fd);
  703. inotify_fd = -1;
  704. SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
  705. "Unable to add inotify watch, falling back to polling: %s",
  706. strerror(errno));
  707. }
  708. }
  709. #endif /* HAVE_INOTIFY */
  710. }
  711. return 0;
  712. }
  713. static int LINUX_JoystickGetCount(void)
  714. {
  715. return numjoysticks;
  716. }
  717. static SDL_joylist_item *JoystickByDevIndex(int device_index)
  718. {
  719. SDL_joylist_item *item = SDL_joylist;
  720. if ((device_index < 0) || (device_index >= numjoysticks)) {
  721. return NULL;
  722. }
  723. while (device_index > 0) {
  724. SDL_assert(item != NULL);
  725. device_index--;
  726. item = item->next;
  727. }
  728. return item;
  729. }
  730. static const char *LINUX_JoystickGetDeviceName(int device_index)
  731. {
  732. return JoystickByDevIndex(device_index)->name;
  733. }
  734. static const char *LINUX_JoystickGetDevicePath(int device_index)
  735. {
  736. return JoystickByDevIndex(device_index)->path;
  737. }
  738. static int LINUX_JoystickGetDevicePlayerIndex(int device_index)
  739. {
  740. return -1;
  741. }
  742. static void LINUX_JoystickSetDevicePlayerIndex(int device_index, int player_index)
  743. {
  744. }
  745. static SDL_JoystickGUID LINUX_JoystickGetDeviceGUID(int device_index)
  746. {
  747. return JoystickByDevIndex(device_index)->guid;
  748. }
  749. /* Function to perform the mapping from device index to the instance id for this index */
  750. static SDL_JoystickID LINUX_JoystickGetDeviceInstanceID(int device_index)
  751. {
  752. return JoystickByDevIndex(device_index)->device_instance;
  753. }
  754. static int allocate_hatdata(SDL_Joystick *joystick)
  755. {
  756. int i;
  757. SDL_AssertJoysticksLocked();
  758. joystick->hwdata->hats =
  759. (struct hwdata_hat *)SDL_malloc(joystick->nhats *
  760. sizeof(struct hwdata_hat));
  761. if (joystick->hwdata->hats == NULL) {
  762. return -1;
  763. }
  764. for (i = 0; i < joystick->nhats; ++i) {
  765. joystick->hwdata->hats[i].axis[0] = 1;
  766. joystick->hwdata->hats[i].axis[1] = 1;
  767. }
  768. return 0;
  769. }
  770. static int allocate_balldata(SDL_Joystick *joystick)
  771. {
  772. int i;
  773. SDL_AssertJoysticksLocked();
  774. joystick->hwdata->balls =
  775. (struct hwdata_ball *)SDL_malloc(joystick->nballs *
  776. sizeof(struct hwdata_ball));
  777. if (joystick->hwdata->balls == NULL) {
  778. return -1;
  779. }
  780. for (i = 0; i < joystick->nballs; ++i) {
  781. joystick->hwdata->balls[i].axis[0] = 0;
  782. joystick->hwdata->balls[i].axis[1] = 0;
  783. }
  784. return 0;
  785. }
  786. static SDL_bool GuessIfAxesAreDigitalHat(struct input_absinfo *absinfo_x, struct input_absinfo *absinfo_y)
  787. {
  788. /* A "hat" is assumed to be a digital input with at most 9 possible states
  789. * (3 per axis: negative/zero/positive), as opposed to a true "axis" which
  790. * can report a continuous range of possible values. Unfortunately the Linux
  791. * joystick interface makes no distinction between digital hat axes and any
  792. * other continuous analog axis, so we have to guess. */
  793. /* If both axes are missing, they're not anything. */
  794. if (absinfo_x == NULL && absinfo_y == NULL) {
  795. return SDL_FALSE;
  796. }
  797. /* If the hint says so, treat all hats as digital. */
  798. if (SDL_GetHintBoolean(SDL_HINT_LINUX_DIGITAL_HATS, SDL_FALSE)) {
  799. return SDL_TRUE;
  800. }
  801. /* If both axes have ranges constrained between -1 and 1, they're definitely digital. */
  802. if ((absinfo_x == NULL || (absinfo_x->minimum == -1 && absinfo_x->maximum == 1)) && (absinfo_y == NULL || (absinfo_y->minimum == -1 && absinfo_y->maximum == 1))) {
  803. return SDL_TRUE;
  804. }
  805. /* If both axes lack fuzz, flat, and resolution values, they're probably digital. */
  806. if ((absinfo_x == NULL || (!absinfo_x->fuzz && !absinfo_x->flat && !absinfo_x->resolution)) && (absinfo_y == NULL || (!absinfo_y->fuzz && !absinfo_y->flat && !absinfo_y->resolution))) {
  807. return SDL_TRUE;
  808. }
  809. /* Otherwise, treat them as analog. */
  810. return SDL_FALSE;
  811. }
  812. static void ConfigJoystick(SDL_Joystick *joystick, int fd)
  813. {
  814. int i, t;
  815. unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
  816. unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
  817. unsigned long relbit[NBITS(REL_MAX)] = { 0 };
  818. unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
  819. Uint8 key_pam_size, abs_pam_size;
  820. SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE);
  821. SDL_bool use_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_HAT_DEADZONES, SDL_TRUE);
  822. SDL_AssertJoysticksLocked();
  823. /* See if this device uses the new unified event API */
  824. if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
  825. (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
  826. (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) {
  827. /* Get the number of buttons, axes, and other thingamajigs */
  828. for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
  829. if (test_bit(i, keybit)) {
  830. #ifdef DEBUG_INPUT_EVENTS
  831. SDL_Log("Joystick has button: 0x%x\n", i);
  832. #endif
  833. joystick->hwdata->key_map[i] = joystick->nbuttons;
  834. joystick->hwdata->has_key[i] = SDL_TRUE;
  835. ++joystick->nbuttons;
  836. }
  837. }
  838. for (i = 0; i < BTN_JOYSTICK; ++i) {
  839. if (test_bit(i, keybit)) {
  840. #ifdef DEBUG_INPUT_EVENTS
  841. SDL_Log("Joystick has button: 0x%x\n", i);
  842. #endif
  843. joystick->hwdata->key_map[i] = joystick->nbuttons;
  844. joystick->hwdata->has_key[i] = SDL_TRUE;
  845. ++joystick->nbuttons;
  846. }
  847. }
  848. for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
  849. int hat_x = -1;
  850. int hat_y = -1;
  851. struct input_absinfo absinfo_x;
  852. struct input_absinfo absinfo_y;
  853. if (test_bit(i, absbit)) {
  854. hat_x = ioctl(fd, EVIOCGABS(i), &absinfo_x);
  855. }
  856. if (test_bit(i + 1, absbit)) {
  857. hat_y = ioctl(fd, EVIOCGABS(i + 1), &absinfo_y);
  858. }
  859. if (GuessIfAxesAreDigitalHat((hat_x < 0 ? (void *)0 : &absinfo_x),
  860. (hat_y < 0 ? (void *)0 : &absinfo_y))) {
  861. const int hat_index = (i - ABS_HAT0X) / 2;
  862. struct hat_axis_correct *correct = &joystick->hwdata->hat_correct[hat_index];
  863. #ifdef DEBUG_INPUT_EVENTS
  864. SDL_Log("Joystick has digital hat: #%d\n", hat_index);
  865. if (hat_x >= 0) {
  866. SDL_Log("X Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
  867. absinfo_x.value, absinfo_x.minimum, absinfo_x.maximum,
  868. absinfo_x.fuzz, absinfo_x.flat, absinfo_x.resolution);
  869. }
  870. if (hat_y >= 0) {
  871. SDL_Log("Y Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
  872. absinfo_y.value, absinfo_y.minimum, absinfo_y.maximum,
  873. absinfo_y.fuzz, absinfo_y.flat, absinfo_y.resolution);
  874. }
  875. #endif /* DEBUG_INPUT_EVENTS */
  876. joystick->hwdata->hats_indices[hat_index] = joystick->nhats;
  877. joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
  878. correct->use_deadzones = use_hat_deadzones;
  879. correct->minimum[0] = (hat_x < 0) ? -1 : absinfo_x.minimum;
  880. correct->maximum[0] = (hat_x < 0) ? 1 : absinfo_x.maximum;
  881. correct->minimum[1] = (hat_y < 0) ? -1 : absinfo_y.minimum;
  882. correct->maximum[1] = (hat_y < 0) ? 1 : absinfo_y.maximum;
  883. ++joystick->nhats;
  884. }
  885. }
  886. for (i = 0; i < ABS_MAX; ++i) {
  887. /* Skip digital hats */
  888. if (i >= ABS_HAT0X && i <= ABS_HAT3Y && joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) {
  889. continue;
  890. }
  891. if (test_bit(i, absbit)) {
  892. struct input_absinfo absinfo;
  893. struct axis_correct *correct = &joystick->hwdata->abs_correct[i];
  894. if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
  895. continue;
  896. }
  897. #ifdef DEBUG_INPUT_EVENTS
  898. SDL_Log("Joystick has absolute axis: 0x%.2x\n", i);
  899. SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
  900. absinfo.value, absinfo.minimum, absinfo.maximum,
  901. absinfo.fuzz, absinfo.flat, absinfo.resolution);
  902. #endif /* DEBUG_INPUT_EVENTS */
  903. joystick->hwdata->abs_map[i] = joystick->naxes;
  904. joystick->hwdata->has_abs[i] = SDL_TRUE;
  905. correct->minimum = absinfo.minimum;
  906. correct->maximum = absinfo.maximum;
  907. if (correct->minimum != correct->maximum) {
  908. if (use_deadzones) {
  909. correct->use_deadzones = SDL_TRUE;
  910. correct->coef[0] = (absinfo.maximum + absinfo.minimum) - 2 * absinfo.flat;
  911. correct->coef[1] = (absinfo.maximum + absinfo.minimum) + 2 * absinfo.flat;
  912. t = ((absinfo.maximum - absinfo.minimum) - 4 * absinfo.flat);
  913. if (t != 0) {
  914. correct->coef[2] = (1 << 28) / t;
  915. } else {
  916. correct->coef[2] = 0;
  917. }
  918. } else {
  919. float value_range = (correct->maximum - correct->minimum);
  920. float output_range = (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN);
  921. correct->scale = (output_range / value_range);
  922. }
  923. }
  924. ++joystick->naxes;
  925. }
  926. }
  927. if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) {
  928. ++joystick->nballs;
  929. }
  930. } else if ((ioctl(fd, JSIOCGBUTTONS, &key_pam_size, sizeof(key_pam_size)) >= 0) &&
  931. (ioctl(fd, JSIOCGAXES, &abs_pam_size, sizeof(abs_pam_size)) >= 0)) {
  932. size_t len;
  933. joystick->hwdata->classic = SDL_TRUE;
  934. len = (KEY_MAX - BTN_MISC + 1) * sizeof(*joystick->hwdata->key_pam);
  935. joystick->hwdata->key_pam = (Uint16 *)SDL_calloc(1, len);
  936. if (joystick->hwdata->key_pam) {
  937. if (ioctl(fd, JSIOCGBTNMAP, joystick->hwdata->key_pam, len) < 0) {
  938. SDL_free(joystick->hwdata->key_pam);
  939. joystick->hwdata->key_pam = NULL;
  940. key_pam_size = 0;
  941. }
  942. } else {
  943. key_pam_size = 0;
  944. }
  945. for (i = 0; i < key_pam_size; ++i) {
  946. Uint16 code = joystick->hwdata->key_pam[i];
  947. #ifdef DEBUG_INPUT_EVENTS
  948. SDL_Log("Joystick has button: 0x%x\n", code);
  949. #endif
  950. joystick->hwdata->key_map[code] = joystick->nbuttons;
  951. joystick->hwdata->has_key[code] = SDL_TRUE;
  952. ++joystick->nbuttons;
  953. }
  954. len = ABS_CNT * sizeof(*joystick->hwdata->abs_pam);
  955. joystick->hwdata->abs_pam = (Uint8 *)SDL_calloc(1, len);
  956. if (joystick->hwdata->abs_pam) {
  957. if (ioctl(fd, JSIOCGAXMAP, joystick->hwdata->abs_pam, len) < 0) {
  958. SDL_free(joystick->hwdata->abs_pam);
  959. joystick->hwdata->abs_pam = NULL;
  960. abs_pam_size = 0;
  961. }
  962. } else {
  963. abs_pam_size = 0;
  964. }
  965. for (i = 0; i < abs_pam_size; ++i) {
  966. Uint8 code = joystick->hwdata->abs_pam[i];
  967. // TODO: is there any way to detect analog hats in advance via this API?
  968. if (code >= ABS_HAT0X && code <= ABS_HAT3Y) {
  969. int hat_index = (code - ABS_HAT0X) / 2;
  970. if (!joystick->hwdata->has_hat[hat_index]) {
  971. #ifdef DEBUG_INPUT_EVENTS
  972. SDL_Log("Joystick has digital hat: #%d\n", hat_index);
  973. #endif
  974. joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
  975. joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
  976. joystick->hwdata->hat_correct[hat_index].minimum[0] = -1;
  977. joystick->hwdata->hat_correct[hat_index].maximum[0] = 1;
  978. joystick->hwdata->hat_correct[hat_index].minimum[1] = -1;
  979. joystick->hwdata->hat_correct[hat_index].maximum[1] = 1;
  980. }
  981. } else {
  982. #ifdef DEBUG_INPUT_EVENTS
  983. SDL_Log("Joystick has absolute axis: 0x%.2x\n", code);
  984. #endif
  985. joystick->hwdata->abs_map[code] = joystick->naxes;
  986. joystick->hwdata->has_abs[code] = SDL_TRUE;
  987. ++joystick->naxes;
  988. }
  989. }
  990. }
  991. /* Allocate data to keep track of these thingamajigs */
  992. if (joystick->nhats > 0) {
  993. if (allocate_hatdata(joystick) < 0) {
  994. joystick->nhats = 0;
  995. }
  996. }
  997. if (joystick->nballs > 0) {
  998. if (allocate_balldata(joystick) < 0) {
  999. joystick->nballs = 0;
  1000. }
  1001. }
  1002. if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0) {
  1003. if (test_bit(FF_RUMBLE, ffbit)) {
  1004. joystick->hwdata->ff_rumble = SDL_TRUE;
  1005. }
  1006. if (test_bit(FF_SINE, ffbit)) {
  1007. joystick->hwdata->ff_sine = SDL_TRUE;
  1008. }
  1009. }
  1010. }
  1011. /* This is used to do the heavy lifting for LINUX_JoystickOpen and
  1012. also LINUX_JoystickGetGamepadMapping, so we can query the hardware
  1013. without adding an opened SDL_Joystick object to the system.
  1014. This expects `joystick->hwdata` to be allocated and will not free it
  1015. on error. Returns -1 on error, 0 on success. */
  1016. static int PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item)
  1017. {
  1018. SDL_AssertJoysticksLocked();
  1019. joystick->hwdata->item = item;
  1020. joystick->hwdata->guid = item->guid;
  1021. joystick->hwdata->effect.id = -1;
  1022. joystick->hwdata->m_bSteamController = item->m_bSteamController;
  1023. SDL_memset(joystick->hwdata->key_map, 0xFF, sizeof(joystick->hwdata->key_map));
  1024. SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map));
  1025. if (item->m_bSteamController) {
  1026. joystick->hwdata->fd = -1;
  1027. SDL_GetSteamControllerInputs(&joystick->nbuttons,
  1028. &joystick->naxes,
  1029. &joystick->nhats);
  1030. } else {
  1031. /* Try read-write first, so we can do rumble */
  1032. int fd = open(item->path, O_RDWR | O_CLOEXEC, 0);
  1033. if (fd < 0) {
  1034. /* Try read-only again, at least we'll get events in this case */
  1035. fd = open(item->path, O_RDONLY | O_CLOEXEC, 0);
  1036. }
  1037. if (fd < 0) {
  1038. return SDL_SetError("Unable to open %s", item->path);
  1039. }
  1040. joystick->hwdata->fd = fd;
  1041. joystick->hwdata->fname = SDL_strdup(item->path);
  1042. if (joystick->hwdata->fname == NULL) {
  1043. close(fd);
  1044. return SDL_OutOfMemory();
  1045. }
  1046. /* Set the joystick to non-blocking read mode */
  1047. fcntl(fd, F_SETFL, O_NONBLOCK);
  1048. /* Get the number of buttons and axes on the joystick */
  1049. ConfigJoystick(joystick, fd);
  1050. }
  1051. return 0;
  1052. }
  1053. /* Function to open a joystick for use.
  1054. The joystick to open is specified by the device index.
  1055. This should fill the nbuttons and naxes fields of the joystick structure.
  1056. It returns 0, or -1 if there is an error.
  1057. */
  1058. static int LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index)
  1059. {
  1060. SDL_joylist_item *item = JoystickByDevIndex(device_index);
  1061. SDL_AssertJoysticksLocked();
  1062. if (item == NULL) {
  1063. return SDL_SetError("No such device");
  1064. }
  1065. joystick->instance_id = item->device_instance;
  1066. joystick->hwdata = (struct joystick_hwdata *)
  1067. SDL_calloc(1, sizeof(*joystick->hwdata));
  1068. if (joystick->hwdata == NULL) {
  1069. return SDL_OutOfMemory();
  1070. }
  1071. if (PrepareJoystickHwdata(joystick, item) == -1) {
  1072. SDL_free(joystick->hwdata);
  1073. joystick->hwdata = NULL;
  1074. return -1; /* SDL_SetError will already have been called */
  1075. }
  1076. SDL_assert(item->hwdata == NULL);
  1077. item->hwdata = joystick->hwdata;
  1078. /* mark joystick as fresh and ready */
  1079. joystick->hwdata->fresh = SDL_TRUE;
  1080. return 0;
  1081. }
  1082. static int LINUX_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
  1083. {
  1084. struct input_event event;
  1085. SDL_AssertJoysticksLocked();
  1086. if (joystick->hwdata->ff_rumble) {
  1087. struct ff_effect *effect = &joystick->hwdata->effect;
  1088. effect->type = FF_RUMBLE;
  1089. effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
  1090. effect->u.rumble.strong_magnitude = low_frequency_rumble;
  1091. effect->u.rumble.weak_magnitude = high_frequency_rumble;
  1092. } else if (joystick->hwdata->ff_sine) {
  1093. /* Scale and average the two rumble strengths */
  1094. Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2);
  1095. struct ff_effect *effect = &joystick->hwdata->effect;
  1096. effect->type = FF_PERIODIC;
  1097. effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
  1098. effect->u.periodic.waveform = FF_SINE;
  1099. effect->u.periodic.magnitude = magnitude;
  1100. } else {
  1101. return SDL_Unsupported();
  1102. }
  1103. if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) {
  1104. /* The kernel may have lost this effect, try to allocate a new one */
  1105. joystick->hwdata->effect.id = -1;
  1106. if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) {
  1107. return SDL_SetError("Couldn't update rumble effect: %s", strerror(errno));
  1108. }
  1109. }
  1110. event.type = EV_FF;
  1111. event.code = joystick->hwdata->effect.id;
  1112. event.value = 1;
  1113. if (write(joystick->hwdata->fd, &event, sizeof(event)) < 0) {
  1114. return SDL_SetError("Couldn't start rumble effect: %s", strerror(errno));
  1115. }
  1116. return 0;
  1117. }
  1118. static int LINUX_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
  1119. {
  1120. return SDL_Unsupported();
  1121. }
  1122. static Uint32 LINUX_JoystickGetCapabilities(SDL_Joystick *joystick)
  1123. {
  1124. Uint32 result = 0;
  1125. SDL_AssertJoysticksLocked();
  1126. if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) {
  1127. result |= SDL_JOYCAP_RUMBLE;
  1128. }
  1129. return result;
  1130. }
  1131. static int LINUX_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
  1132. {
  1133. return SDL_Unsupported();
  1134. }
  1135. static int LINUX_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
  1136. {
  1137. return SDL_Unsupported();
  1138. }
  1139. static int LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
  1140. {
  1141. return SDL_Unsupported();
  1142. }
  1143. static void HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value)
  1144. {
  1145. int hatnum;
  1146. struct hwdata_hat *the_hat;
  1147. struct hat_axis_correct *correct;
  1148. const Uint8 position_map[3][3] = {
  1149. { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
  1150. { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
  1151. { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
  1152. };
  1153. SDL_AssertJoysticksLocked();
  1154. hatnum = stick->hwdata->hats_indices[hatidx];
  1155. the_hat = &stick->hwdata->hats[hatnum];
  1156. correct = &stick->hwdata->hat_correct[hatidx];
  1157. /* Hopefully we detected any analog axes and left them as is rather than trying
  1158. * to use them as digital hats, but just in case, the deadzones here will
  1159. * prevent the slightest of twitches on an analog axis from registering as a hat
  1160. * movement. If the axes really are digital, this won't hurt since they should
  1161. * only ever be sending min, 0, or max anyway. */
  1162. if (value < 0) {
  1163. if (value <= correct->minimum[axis]) {
  1164. correct->minimum[axis] = value;
  1165. value = 0;
  1166. } else if (!correct->use_deadzones || value < correct->minimum[axis] / 3) {
  1167. value = 0;
  1168. } else {
  1169. value = 1;
  1170. }
  1171. } else if (value > 0) {
  1172. if (value >= correct->maximum[axis]) {
  1173. correct->maximum[axis] = value;
  1174. value = 2;
  1175. } else if (!correct->use_deadzones || value > correct->maximum[axis] / 3) {
  1176. value = 2;
  1177. } else {
  1178. value = 1;
  1179. }
  1180. } else { // value == 0
  1181. value = 1;
  1182. }
  1183. if (value != the_hat->axis[axis]) {
  1184. the_hat->axis[axis] = value;
  1185. SDL_PrivateJoystickHat(stick, hatnum,
  1186. position_map[the_hat->axis[1]][the_hat->axis[0]]);
  1187. }
  1188. }
  1189. static void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
  1190. {
  1191. SDL_AssertJoysticksLocked();
  1192. stick->hwdata->balls[ball].axis[axis] += value;
  1193. }
  1194. static int AxisCorrect(SDL_Joystick *joystick, int which, int value)
  1195. {
  1196. struct axis_correct *correct;
  1197. SDL_AssertJoysticksLocked();
  1198. correct = &joystick->hwdata->abs_correct[which];
  1199. if (correct->minimum != correct->maximum) {
  1200. if (correct->use_deadzones) {
  1201. value *= 2;
  1202. if (value > correct->coef[0]) {
  1203. if (value < correct->coef[1]) {
  1204. return 0;
  1205. }
  1206. value -= correct->coef[1];
  1207. } else {
  1208. value -= correct->coef[0];
  1209. }
  1210. value *= correct->coef[2];
  1211. value >>= 13;
  1212. } else {
  1213. value = (int)SDL_floorf((value - correct->minimum) * correct->scale + SDL_JOYSTICK_AXIS_MIN + 0.5f);
  1214. }
  1215. }
  1216. /* Clamp and return */
  1217. if (value < SDL_JOYSTICK_AXIS_MIN) {
  1218. return SDL_JOYSTICK_AXIS_MIN;
  1219. }
  1220. if (value > SDL_JOYSTICK_AXIS_MAX) {
  1221. return SDL_JOYSTICK_AXIS_MAX;
  1222. }
  1223. return value;
  1224. }
  1225. static void PollAllValues(SDL_Joystick *joystick)
  1226. {
  1227. struct input_absinfo absinfo;
  1228. unsigned long keyinfo[NBITS(KEY_MAX)];
  1229. int i;
  1230. SDL_AssertJoysticksLocked();
  1231. /* Poll all axis */
  1232. for (i = ABS_X; i < ABS_MAX; i++) {
  1233. /* We don't need to test for digital hats here, they won't have has_abs[] set */
  1234. if (joystick->hwdata->has_abs[i]) {
  1235. if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
  1236. absinfo.value = AxisCorrect(joystick, i, absinfo.value);
  1237. #ifdef DEBUG_INPUT_EVENTS
  1238. SDL_Log("Joystick : Re-read Axis %d (%d) val= %d\n",
  1239. joystick->hwdata->abs_map[i], i, absinfo.value);
  1240. #endif
  1241. SDL_PrivateJoystickAxis(joystick,
  1242. joystick->hwdata->abs_map[i],
  1243. absinfo.value);
  1244. }
  1245. }
  1246. }
  1247. /* Poll all digital hats */
  1248. for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++) {
  1249. const int baseaxis = i - ABS_HAT0X;
  1250. const int hatidx = baseaxis / 2;
  1251. SDL_assert(hatidx < SDL_arraysize(joystick->hwdata->has_hat));
  1252. /* We don't need to test for analog axes here, they won't have has_hat[] set */
  1253. if (joystick->hwdata->has_hat[hatidx]) {
  1254. if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
  1255. const int hataxis = baseaxis % 2;
  1256. HandleHat(joystick, hatidx, hataxis, absinfo.value);
  1257. }
  1258. }
  1259. }
  1260. /* Poll all buttons */
  1261. SDL_zeroa(keyinfo);
  1262. if (ioctl(joystick->hwdata->fd, EVIOCGKEY(sizeof(keyinfo)), keyinfo) >= 0) {
  1263. for (i = 0; i < KEY_MAX; i++) {
  1264. if (joystick->hwdata->has_key[i]) {
  1265. const Uint8 value = test_bit(i, keyinfo) ? SDL_PRESSED : SDL_RELEASED;
  1266. #ifdef DEBUG_INPUT_EVENTS
  1267. SDL_Log("Joystick : Re-read Button %d (%d) val= %d\n",
  1268. joystick->hwdata->key_map[i], i, value);
  1269. #endif
  1270. SDL_PrivateJoystickButton(joystick,
  1271. joystick->hwdata->key_map[i], value);
  1272. }
  1273. }
  1274. }
  1275. /* Joyballs are relative input, so there's no poll state. Events only! */
  1276. }
  1277. static void HandleInputEvents(SDL_Joystick *joystick)
  1278. {
  1279. struct input_event events[32];
  1280. int i, len, code, hat_index;
  1281. SDL_AssertJoysticksLocked();
  1282. if (joystick->hwdata->fresh) {
  1283. PollAllValues(joystick);
  1284. joystick->hwdata->fresh = SDL_FALSE;
  1285. }
  1286. while ((len = read(joystick->hwdata->fd, events, sizeof(events))) > 0) {
  1287. len /= sizeof(events[0]);
  1288. for (i = 0; i < len; ++i) {
  1289. code = events[i].code;
  1290. /* If the kernel sent a SYN_DROPPED, we are supposed to ignore the
  1291. rest of the packet (the end of it signified by a SYN_REPORT) */
  1292. if (joystick->hwdata->recovering_from_dropped &&
  1293. ((events[i].type != EV_SYN) || (code != SYN_REPORT))) {
  1294. continue;
  1295. }
  1296. switch (events[i].type) {
  1297. case EV_KEY:
  1298. SDL_PrivateJoystickButton(joystick,
  1299. joystick->hwdata->key_map[code],
  1300. events[i].value);
  1301. break;
  1302. case EV_ABS:
  1303. switch (code) {
  1304. case ABS_HAT0X:
  1305. case ABS_HAT0Y:
  1306. case ABS_HAT1X:
  1307. case ABS_HAT1Y:
  1308. case ABS_HAT2X:
  1309. case ABS_HAT2Y:
  1310. case ABS_HAT3X:
  1311. case ABS_HAT3Y:
  1312. hat_index = (code - ABS_HAT0X) / 2;
  1313. if (joystick->hwdata->has_hat[hat_index]) {
  1314. HandleHat(joystick, hat_index, code % 2, events[i].value);
  1315. break;
  1316. }
  1317. SDL_FALLTHROUGH;
  1318. default:
  1319. events[i].value = AxisCorrect(joystick, code, events[i].value);
  1320. SDL_PrivateJoystickAxis(joystick,
  1321. joystick->hwdata->abs_map[code],
  1322. events[i].value);
  1323. break;
  1324. }
  1325. break;
  1326. case EV_REL:
  1327. switch (code) {
  1328. case REL_X:
  1329. case REL_Y:
  1330. code -= REL_X;
  1331. HandleBall(joystick, code / 2, code % 2, events[i].value);
  1332. break;
  1333. default:
  1334. break;
  1335. }
  1336. break;
  1337. case EV_SYN:
  1338. switch (code) {
  1339. case SYN_DROPPED:
  1340. #ifdef DEBUG_INPUT_EVENTS
  1341. SDL_Log("Event SYN_DROPPED detected\n");
  1342. #endif
  1343. joystick->hwdata->recovering_from_dropped = SDL_TRUE;
  1344. break;
  1345. case SYN_REPORT:
  1346. if (joystick->hwdata->recovering_from_dropped) {
  1347. joystick->hwdata->recovering_from_dropped = SDL_FALSE;
  1348. PollAllValues(joystick); /* try to sync up to current state now */
  1349. }
  1350. break;
  1351. default:
  1352. break;
  1353. }
  1354. default:
  1355. break;
  1356. }
  1357. }
  1358. }
  1359. if (errno == ENODEV) {
  1360. /* We have to wait until the JoystickDetect callback to remove this */
  1361. joystick->hwdata->gone = SDL_TRUE;
  1362. }
  1363. }
  1364. static void HandleClassicEvents(SDL_Joystick *joystick)
  1365. {
  1366. struct js_event events[32];
  1367. int i, len, code, hat_index;
  1368. SDL_AssertJoysticksLocked();
  1369. joystick->hwdata->fresh = SDL_FALSE;
  1370. while ((len = read(joystick->hwdata->fd, events, sizeof(events))) > 0) {
  1371. len /= sizeof(events[0]);
  1372. for (i = 0; i < len; ++i) {
  1373. switch (events[i].type) {
  1374. case JS_EVENT_BUTTON:
  1375. code = joystick->hwdata->key_pam[events[i].number];
  1376. SDL_PrivateJoystickButton(joystick,
  1377. joystick->hwdata->key_map[code],
  1378. events[i].value);
  1379. break;
  1380. case JS_EVENT_AXIS:
  1381. code = joystick->hwdata->abs_pam[events[i].number];
  1382. switch (code) {
  1383. case ABS_HAT0X:
  1384. case ABS_HAT0Y:
  1385. case ABS_HAT1X:
  1386. case ABS_HAT1Y:
  1387. case ABS_HAT2X:
  1388. case ABS_HAT2Y:
  1389. case ABS_HAT3X:
  1390. case ABS_HAT3Y:
  1391. hat_index = (code - ABS_HAT0X) / 2;
  1392. if (joystick->hwdata->has_hat[hat_index]) {
  1393. HandleHat(joystick, hat_index, code % 2, events[i].value);
  1394. break;
  1395. }
  1396. SDL_FALLTHROUGH;
  1397. default:
  1398. SDL_PrivateJoystickAxis(joystick,
  1399. joystick->hwdata->abs_map[code],
  1400. events[i].value);
  1401. break;
  1402. }
  1403. }
  1404. }
  1405. }
  1406. }
  1407. static void LINUX_JoystickUpdate(SDL_Joystick *joystick)
  1408. {
  1409. int i;
  1410. SDL_AssertJoysticksLocked();
  1411. if (joystick->hwdata->m_bSteamController) {
  1412. SDL_UpdateSteamController(joystick);
  1413. return;
  1414. }
  1415. if (joystick->hwdata->classic) {
  1416. HandleClassicEvents(joystick);
  1417. } else {
  1418. HandleInputEvents(joystick);
  1419. }
  1420. /* Deliver ball motion updates */
  1421. for (i = 0; i < joystick->nballs; ++i) {
  1422. int xrel, yrel;
  1423. xrel = joystick->hwdata->balls[i].axis[0];
  1424. yrel = joystick->hwdata->balls[i].axis[1];
  1425. if (xrel || yrel) {
  1426. joystick->hwdata->balls[i].axis[0] = 0;
  1427. joystick->hwdata->balls[i].axis[1] = 0;
  1428. SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel);
  1429. }
  1430. }
  1431. }
  1432. /* Function to close a joystick after use */
  1433. static void LINUX_JoystickClose(SDL_Joystick *joystick)
  1434. {
  1435. SDL_AssertJoysticksLocked();
  1436. if (joystick->hwdata) {
  1437. if (joystick->hwdata->effect.id >= 0) {
  1438. ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
  1439. joystick->hwdata->effect.id = -1;
  1440. }
  1441. if (joystick->hwdata->fd >= 0) {
  1442. close(joystick->hwdata->fd);
  1443. }
  1444. if (joystick->hwdata->item) {
  1445. joystick->hwdata->item->hwdata = NULL;
  1446. }
  1447. SDL_free(joystick->hwdata->key_pam);
  1448. SDL_free(joystick->hwdata->abs_pam);
  1449. SDL_free(joystick->hwdata->hats);
  1450. SDL_free(joystick->hwdata->balls);
  1451. SDL_free(joystick->hwdata->fname);
  1452. SDL_free(joystick->hwdata);
  1453. }
  1454. }
  1455. /* Function to perform any system-specific joystick related cleanup */
  1456. static void LINUX_JoystickQuit(void)
  1457. {
  1458. SDL_joylist_item *item = NULL;
  1459. SDL_joylist_item *next = NULL;
  1460. if (inotify_fd >= 0) {
  1461. close(inotify_fd);
  1462. inotify_fd = -1;
  1463. }
  1464. for (item = SDL_joylist; item; item = next) {
  1465. next = item->next;
  1466. FreeJoylistItem(item);
  1467. }
  1468. SDL_joylist = SDL_joylist_tail = NULL;
  1469. numjoysticks = 0;
  1470. #if SDL_USE_LIBUDEV
  1471. if (enumeration_method == ENUMERATION_LIBUDEV) {
  1472. SDL_UDEV_DelCallback(joystick_udev_callback);
  1473. SDL_UDEV_Quit();
  1474. }
  1475. #endif
  1476. SDL_QuitSteamControllers();
  1477. }
  1478. /*
  1479. This is based on the Linux Gamepad Specification
  1480. available at: https://www.kernel.org/doc/html/v4.15/input/gamepad.html
  1481. and the Android gamepad documentation,
  1482. https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input
  1483. */
  1484. static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
  1485. {
  1486. SDL_Joystick *joystick;
  1487. SDL_joylist_item *item = JoystickByDevIndex(device_index);
  1488. enum {
  1489. MAPPED_TRIGGER_LEFT = 0x1,
  1490. MAPPED_TRIGGER_RIGHT = 0x2,
  1491. MAPPED_TRIGGER_BOTH = 0x3,
  1492. MAPPED_DPAD_UP = 0x1,
  1493. MAPPED_DPAD_DOWN = 0x2,
  1494. MAPPED_DPAD_LEFT = 0x4,
  1495. MAPPED_DPAD_RIGHT = 0x8,
  1496. MAPPED_DPAD_ALL = 0xF,
  1497. };
  1498. unsigned int mapped;
  1499. SDL_AssertJoysticksLocked();
  1500. if (item->checked_mapping) {
  1501. if (item->mapping) {
  1502. SDL_memcpy(out, item->mapping, sizeof(*out));
  1503. #ifdef DEBUG_GAMEPAD_MAPPING
  1504. SDL_Log("Prior mapping for device %d", device_index);
  1505. #endif
  1506. return SDL_TRUE;
  1507. } else {
  1508. return SDL_FALSE;
  1509. }
  1510. }
  1511. /* We temporarily open the device to check how it's configured. Make
  1512. a fake SDL_Joystick object to do so. */
  1513. joystick = (SDL_Joystick *)SDL_calloc(sizeof(*joystick), 1);
  1514. if (joystick == NULL) {
  1515. SDL_OutOfMemory();
  1516. return SDL_FALSE;
  1517. }
  1518. joystick->magic = &SDL_joystick_magic;
  1519. SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
  1520. joystick->hwdata = (struct joystick_hwdata *)
  1521. SDL_calloc(1, sizeof(*joystick->hwdata));
  1522. if (joystick->hwdata == NULL) {
  1523. SDL_free(joystick);
  1524. SDL_OutOfMemory();
  1525. return SDL_FALSE;
  1526. }
  1527. item->checked_mapping = SDL_TRUE;
  1528. if (PrepareJoystickHwdata(joystick, item) == -1) {
  1529. SDL_free(joystick->hwdata);
  1530. SDL_free(joystick);
  1531. return SDL_FALSE; /* SDL_SetError will already have been called */
  1532. }
  1533. /* don't assign `item->hwdata` so it's not in any global state. */
  1534. /* it is now safe to call LINUX_JoystickClose on this fake joystick. */
  1535. if (!joystick->hwdata->has_key[BTN_GAMEPAD]) {
  1536. /* Not a gamepad according to the specs. */
  1537. LINUX_JoystickClose(joystick);
  1538. SDL_free(joystick);
  1539. return SDL_FALSE;
  1540. }
  1541. /* We have a gamepad, start filling out the mappings */
  1542. #ifdef DEBUG_GAMEPAD_MAPPING
  1543. SDL_Log("Mapping %s (VID/PID 0x%.4x/0x%.4x)", item->name, SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick));
  1544. #endif
  1545. if (joystick->hwdata->has_key[BTN_A]) {
  1546. out->a.kind = EMappingKind_Button;
  1547. out->a.target = joystick->hwdata->key_map[BTN_A];
  1548. #ifdef DEBUG_GAMEPAD_MAPPING
  1549. SDL_Log("Mapped A to button %d (BTN_A)", out->a.target);
  1550. #endif
  1551. }
  1552. if (joystick->hwdata->has_key[BTN_B]) {
  1553. out->b.kind = EMappingKind_Button;
  1554. out->b.target = joystick->hwdata->key_map[BTN_B];
  1555. #ifdef DEBUG_GAMEPAD_MAPPING
  1556. SDL_Log("Mapped B to button %d (BTN_B)", out->b.target);
  1557. #endif
  1558. }
  1559. /* Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH */
  1560. if (SDL_JoystickGetVendor(joystick) == USB_VENDOR_SONY) {
  1561. if (joystick->hwdata->has_key[BTN_WEST]) {
  1562. out->x.kind = EMappingKind_Button;
  1563. out->x.target = joystick->hwdata->key_map[BTN_WEST];
  1564. #ifdef DEBUG_GAMEPAD_MAPPING
  1565. SDL_Log("Mapped X to button %d (BTN_WEST)", out->x.target);
  1566. #endif
  1567. }
  1568. if (joystick->hwdata->has_key[BTN_NORTH]) {
  1569. out->y.kind = EMappingKind_Button;
  1570. out->y.target = joystick->hwdata->key_map[BTN_NORTH];
  1571. #ifdef DEBUG_GAMEPAD_MAPPING
  1572. SDL_Log("Mapped Y to button %d (BTN_NORTH)", out->y.target);
  1573. #endif
  1574. }
  1575. } else {
  1576. if (joystick->hwdata->has_key[BTN_X]) {
  1577. out->x.kind = EMappingKind_Button;
  1578. out->x.target = joystick->hwdata->key_map[BTN_X];
  1579. #ifdef DEBUG_GAMEPAD_MAPPING
  1580. SDL_Log("Mapped X to button %d (BTN_X)", out->x.target);
  1581. #endif
  1582. }
  1583. if (joystick->hwdata->has_key[BTN_Y]) {
  1584. out->y.kind = EMappingKind_Button;
  1585. out->y.target = joystick->hwdata->key_map[BTN_Y];
  1586. #ifdef DEBUG_GAMEPAD_MAPPING
  1587. SDL_Log("Mapped Y to button %d (BTN_Y)", out->y.target);
  1588. #endif
  1589. }
  1590. }
  1591. if (joystick->hwdata->has_key[BTN_SELECT]) {
  1592. out->back.kind = EMappingKind_Button;
  1593. out->back.target = joystick->hwdata->key_map[BTN_SELECT];
  1594. #ifdef DEBUG_GAMEPAD_MAPPING
  1595. SDL_Log("Mapped BACK to button %d (BTN_SELECT)", out->back.target);
  1596. #endif
  1597. }
  1598. if (joystick->hwdata->has_key[BTN_START]) {
  1599. out->start.kind = EMappingKind_Button;
  1600. out->start.target = joystick->hwdata->key_map[BTN_START];
  1601. #ifdef DEBUG_GAMEPAD_MAPPING
  1602. SDL_Log("Mapped START to button %d (BTN_START)", out->start.target);
  1603. #endif
  1604. }
  1605. if (joystick->hwdata->has_key[BTN_THUMBL]) {
  1606. out->leftstick.kind = EMappingKind_Button;
  1607. out->leftstick.target = joystick->hwdata->key_map[BTN_THUMBL];
  1608. #ifdef DEBUG_GAMEPAD_MAPPING
  1609. SDL_Log("Mapped LEFTSTICK to button %d (BTN_THUMBL)", out->leftstick.target);
  1610. #endif
  1611. }
  1612. if (joystick->hwdata->has_key[BTN_THUMBR]) {
  1613. out->rightstick.kind = EMappingKind_Button;
  1614. out->rightstick.target = joystick->hwdata->key_map[BTN_THUMBR];
  1615. #ifdef DEBUG_GAMEPAD_MAPPING
  1616. SDL_Log("Mapped RIGHTSTICK to button %d (BTN_THUMBR)", out->rightstick.target);
  1617. #endif
  1618. }
  1619. if (joystick->hwdata->has_key[BTN_MODE]) {
  1620. out->guide.kind = EMappingKind_Button;
  1621. out->guide.target = joystick->hwdata->key_map[BTN_MODE];
  1622. #ifdef DEBUG_GAMEPAD_MAPPING
  1623. SDL_Log("Mapped GUIDE to button %d (BTN_MODE)", out->guide.target);
  1624. #endif
  1625. }
  1626. /*
  1627. According to the specs the D-Pad, the shoulder buttons and the triggers
  1628. can be digital, or analog, or both at the same time.
  1629. */
  1630. /* Prefer digital shoulder buttons, but settle for digital or analog hat. */
  1631. mapped = 0;
  1632. if (joystick->hwdata->has_key[BTN_TL]) {
  1633. out->leftshoulder.kind = EMappingKind_Button;
  1634. out->leftshoulder.target = joystick->hwdata->key_map[BTN_TL];
  1635. mapped |= 0x1;
  1636. #ifdef DEBUG_GAMEPAD_MAPPING
  1637. SDL_Log("Mapped LEFTSHOULDER to button %d (BTN_TL)", out->leftshoulder.target);
  1638. #endif
  1639. }
  1640. if (joystick->hwdata->has_key[BTN_TR]) {
  1641. out->rightshoulder.kind = EMappingKind_Button;
  1642. out->rightshoulder.target = joystick->hwdata->key_map[BTN_TR];
  1643. mapped |= 0x2;
  1644. #ifdef DEBUG_GAMEPAD_MAPPING
  1645. SDL_Log("Mapped RIGHTSHOULDER to button %d (BTN_TR)", out->rightshoulder.target);
  1646. #endif
  1647. }
  1648. if (mapped != 0x3 && joystick->hwdata->has_hat[1]) {
  1649. int hat = joystick->hwdata->hats_indices[1] << 4;
  1650. out->leftshoulder.kind = EMappingKind_Hat;
  1651. out->rightshoulder.kind = EMappingKind_Hat;
  1652. out->leftshoulder.target = hat | 0x4;
  1653. out->rightshoulder.target = hat | 0x2;
  1654. mapped |= 0x3;
  1655. #ifdef DEBUG_GAMEPAD_MAPPING
  1656. SDL_Log("Mapped LEFT+RIGHTSHOULDER to hat 1 (ABS_HAT1X, ABS_HAT1Y)");
  1657. #endif
  1658. }
  1659. if (!(mapped & 0x1) && joystick->hwdata->has_abs[ABS_HAT1Y]) {
  1660. out->leftshoulder.kind = EMappingKind_Axis;
  1661. out->leftshoulder.target = joystick->hwdata->abs_map[ABS_HAT1Y];
  1662. mapped |= 0x1;
  1663. #ifdef DEBUG_GAMEPAD_MAPPING
  1664. SDL_Log("Mapped LEFTSHOULDER to axis %d (ABS_HAT1Y)", out->leftshoulder.target);
  1665. #endif
  1666. }
  1667. if (!(mapped & 0x2) && joystick->hwdata->has_abs[ABS_HAT1X]) {
  1668. out->rightshoulder.kind = EMappingKind_Axis;
  1669. out->rightshoulder.target = joystick->hwdata->abs_map[ABS_HAT1X];
  1670. mapped |= 0x2;
  1671. #ifdef DEBUG_GAMEPAD_MAPPING
  1672. SDL_Log("Mapped RIGHTSHOULDER to axis %d (ABS_HAT1X)", out->rightshoulder.target);
  1673. #endif
  1674. }
  1675. /* Prefer analog triggers, but settle for digital hat or buttons. */
  1676. mapped = 0;
  1677. /* Unfortunately there are several conventions for how analog triggers
  1678. * are represented as absolute axes:
  1679. *
  1680. * - Linux Gamepad Specification:
  1681. * LT = ABS_HAT2Y, RT = ABS_HAT2X
  1682. * - Android (and therefore many Bluetooth controllers):
  1683. * LT = ABS_BRAKE, RT = ABS_GAS
  1684. * - De facto standard for older Xbox and Playstation controllers:
  1685. * LT = ABS_Z, RT = ABS_RZ
  1686. *
  1687. * We try each one in turn. */
  1688. if (joystick->hwdata->has_abs[ABS_HAT2Y]) {
  1689. /* Linux Gamepad Specification */
  1690. out->lefttrigger.kind = EMappingKind_Axis;
  1691. out->lefttrigger.target = joystick->hwdata->abs_map[ABS_HAT2Y];
  1692. mapped |= MAPPED_TRIGGER_LEFT;
  1693. #ifdef DEBUG_GAMEPAD_MAPPING
  1694. SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_HAT2Y)", out->lefttrigger.target);
  1695. #endif
  1696. } else if (joystick->hwdata->has_abs[ABS_BRAKE]) {
  1697. /* Android convention */
  1698. out->lefttrigger.kind = EMappingKind_Axis;
  1699. out->lefttrigger.target = joystick->hwdata->abs_map[ABS_BRAKE];
  1700. mapped |= MAPPED_TRIGGER_LEFT;
  1701. #ifdef DEBUG_GAMEPAD_MAPPING
  1702. SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_BRAKE)", out->lefttrigger.target);
  1703. #endif
  1704. } else if (joystick->hwdata->has_abs[ABS_Z]) {
  1705. /* De facto standard for Xbox 360 and Playstation gamepads */
  1706. out->lefttrigger.kind = EMappingKind_Axis;
  1707. out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z];
  1708. mapped |= MAPPED_TRIGGER_LEFT;
  1709. #ifdef DEBUG_GAMEPAD_MAPPING
  1710. SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_Z)", out->lefttrigger.target);
  1711. #endif
  1712. }
  1713. if (joystick->hwdata->has_abs[ABS_HAT2X]) {
  1714. /* Linux Gamepad Specification */
  1715. out->righttrigger.kind = EMappingKind_Axis;
  1716. out->righttrigger.target = joystick->hwdata->abs_map[ABS_HAT2X];
  1717. mapped |= MAPPED_TRIGGER_RIGHT;
  1718. #ifdef DEBUG_GAMEPAD_MAPPING
  1719. SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_HAT2X)", out->righttrigger.target);
  1720. #endif
  1721. } else if (joystick->hwdata->has_abs[ABS_GAS]) {
  1722. /* Android convention */
  1723. out->righttrigger.kind = EMappingKind_Axis;
  1724. out->righttrigger.target = joystick->hwdata->abs_map[ABS_GAS];
  1725. mapped |= MAPPED_TRIGGER_RIGHT;
  1726. #ifdef DEBUG_GAMEPAD_MAPPING
  1727. SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_GAS)", out->righttrigger.target);
  1728. #endif
  1729. } else if (joystick->hwdata->has_abs[ABS_RZ]) {
  1730. /* De facto standard for Xbox 360 and Playstation gamepads */
  1731. out->righttrigger.kind = EMappingKind_Axis;
  1732. out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ];
  1733. mapped |= MAPPED_TRIGGER_RIGHT;
  1734. #ifdef DEBUG_GAMEPAD_MAPPING
  1735. SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_RZ)", out->righttrigger.target);
  1736. #endif
  1737. }
  1738. if (mapped != MAPPED_TRIGGER_BOTH && joystick->hwdata->has_hat[2]) {
  1739. int hat = joystick->hwdata->hats_indices[2] << 4;
  1740. out->lefttrigger.kind = EMappingKind_Hat;
  1741. out->righttrigger.kind = EMappingKind_Hat;
  1742. out->lefttrigger.target = hat | 0x4;
  1743. out->righttrigger.target = hat | 0x2;
  1744. mapped |= MAPPED_TRIGGER_BOTH;
  1745. #ifdef DEBUG_GAMEPAD_MAPPING
  1746. SDL_Log("Mapped LEFT+RIGHTTRIGGER to hat 2 (ABS_HAT2X, ABS_HAT2Y)");
  1747. #endif
  1748. }
  1749. if (!(mapped & MAPPED_TRIGGER_LEFT) && joystick->hwdata->has_key[BTN_TL2]) {
  1750. out->lefttrigger.kind = EMappingKind_Button;
  1751. out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
  1752. mapped |= MAPPED_TRIGGER_LEFT;
  1753. #ifdef DEBUG_GAMEPAD_MAPPING
  1754. SDL_Log("Mapped LEFTTRIGGER to button %d (BTN_TL2)", out->lefttrigger.target);
  1755. #endif
  1756. }
  1757. if (!(mapped & MAPPED_TRIGGER_RIGHT) && joystick->hwdata->has_key[BTN_TR2]) {
  1758. out->righttrigger.kind = EMappingKind_Button;
  1759. out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
  1760. mapped |= MAPPED_TRIGGER_RIGHT;
  1761. #ifdef DEBUG_GAMEPAD_MAPPING
  1762. SDL_Log("Mapped RIGHTTRIGGER to button %d (BTN_TR2)", out->righttrigger.target);
  1763. #endif
  1764. }
  1765. /* Prefer digital D-Pad buttons, but settle for digital or analog hat. */
  1766. mapped = 0;
  1767. if (joystick->hwdata->has_key[BTN_DPAD_UP]) {
  1768. out->dpup.kind = EMappingKind_Button;
  1769. out->dpup.target = joystick->hwdata->key_map[BTN_DPAD_UP];
  1770. mapped |= MAPPED_DPAD_UP;
  1771. #ifdef DEBUG_GAMEPAD_MAPPING
  1772. SDL_Log("Mapped DPUP to button %d (BTN_DPAD_UP)", out->dpup.target);
  1773. #endif
  1774. }
  1775. if (joystick->hwdata->has_key[BTN_DPAD_DOWN]) {
  1776. out->dpdown.kind = EMappingKind_Button;
  1777. out->dpdown.target = joystick->hwdata->key_map[BTN_DPAD_DOWN];
  1778. mapped |= MAPPED_DPAD_DOWN;
  1779. #ifdef DEBUG_GAMEPAD_MAPPING
  1780. SDL_Log("Mapped DPDOWN to button %d (BTN_DPAD_DOWN)", out->dpdown.target);
  1781. #endif
  1782. }
  1783. if (joystick->hwdata->has_key[BTN_DPAD_LEFT]) {
  1784. out->dpleft.kind = EMappingKind_Button;
  1785. out->dpleft.target = joystick->hwdata->key_map[BTN_DPAD_LEFT];
  1786. mapped |= MAPPED_DPAD_LEFT;
  1787. #ifdef DEBUG_GAMEPAD_MAPPING
  1788. SDL_Log("Mapped DPLEFT to button %d (BTN_DPAD_LEFT)", out->dpleft.target);
  1789. #endif
  1790. }
  1791. if (joystick->hwdata->has_key[BTN_DPAD_RIGHT]) {
  1792. out->dpright.kind = EMappingKind_Button;
  1793. out->dpright.target = joystick->hwdata->key_map[BTN_DPAD_RIGHT];
  1794. mapped |= MAPPED_DPAD_RIGHT;
  1795. #ifdef DEBUG_GAMEPAD_MAPPING
  1796. SDL_Log("Mapped DPRIGHT to button %d (BTN_DPAD_RIGHT)", out->dpright.target);
  1797. #endif
  1798. }
  1799. if (mapped != MAPPED_DPAD_ALL) {
  1800. if (joystick->hwdata->has_hat[0]) {
  1801. int hat = joystick->hwdata->hats_indices[0] << 4;
  1802. out->dpleft.kind = EMappingKind_Hat;
  1803. out->dpright.kind = EMappingKind_Hat;
  1804. out->dpup.kind = EMappingKind_Hat;
  1805. out->dpdown.kind = EMappingKind_Hat;
  1806. out->dpleft.target = hat | 0x8;
  1807. out->dpright.target = hat | 0x2;
  1808. out->dpup.target = hat | 0x1;
  1809. out->dpdown.target = hat | 0x4;
  1810. mapped |= MAPPED_DPAD_ALL;
  1811. #ifdef DEBUG_GAMEPAD_MAPPING
  1812. SDL_Log("Mapped DPUP+DOWN+LEFT+RIGHT to hat 0 (ABS_HAT0X, ABS_HAT0Y)");
  1813. #endif
  1814. } else if (joystick->hwdata->has_abs[ABS_HAT0X] && joystick->hwdata->has_abs[ABS_HAT0Y]) {
  1815. out->dpleft.kind = EMappingKind_Axis;
  1816. out->dpright.kind = EMappingKind_Axis;
  1817. out->dpup.kind = EMappingKind_Axis;
  1818. out->dpdown.kind = EMappingKind_Axis;
  1819. out->dpleft.target = joystick->hwdata->abs_map[ABS_HAT0X];
  1820. out->dpright.target = joystick->hwdata->abs_map[ABS_HAT0X];
  1821. out->dpup.target = joystick->hwdata->abs_map[ABS_HAT0Y];
  1822. out->dpdown.target = joystick->hwdata->abs_map[ABS_HAT0Y];
  1823. mapped |= MAPPED_DPAD_ALL;
  1824. #ifdef DEBUG_GAMEPAD_MAPPING
  1825. SDL_Log("Mapped DPUP+DOWN to axis %d (ABS_HAT0Y)", out->dpup.target);
  1826. SDL_Log("Mapped DPLEFT+RIGHT to axis %d (ABS_HAT0X)", out->dpleft.target);
  1827. #endif
  1828. }
  1829. }
  1830. if (joystick->hwdata->has_abs[ABS_X] && joystick->hwdata->has_abs[ABS_Y]) {
  1831. out->leftx.kind = EMappingKind_Axis;
  1832. out->lefty.kind = EMappingKind_Axis;
  1833. out->leftx.target = joystick->hwdata->abs_map[ABS_X];
  1834. out->lefty.target = joystick->hwdata->abs_map[ABS_Y];
  1835. #ifdef DEBUG_GAMEPAD_MAPPING
  1836. SDL_Log("Mapped LEFTX to axis %d (ABS_X)", out->leftx.target);
  1837. SDL_Log("Mapped LEFTY to axis %d (ABS_Y)", out->lefty.target);
  1838. #endif
  1839. }
  1840. /* The Linux Gamepad Specification uses the RX and RY axes,
  1841. * originally intended to represent X and Y rotation, as a second
  1842. * joystick. This is common for USB gamepads, and also many Bluetooth
  1843. * gamepads, particularly older ones.
  1844. *
  1845. * The Android mapping convention used by many Bluetooth controllers
  1846. * instead uses the Z axis as a secondary X axis, and the RZ axis as
  1847. * a secondary Y axis. */
  1848. if (joystick->hwdata->has_abs[ABS_RX] && joystick->hwdata->has_abs[ABS_RY]) {
  1849. /* Linux Gamepad Specification, Xbox 360, Playstation etc. */
  1850. out->rightx.kind = EMappingKind_Axis;
  1851. out->righty.kind = EMappingKind_Axis;
  1852. out->rightx.target = joystick->hwdata->abs_map[ABS_RX];
  1853. out->righty.target = joystick->hwdata->abs_map[ABS_RY];
  1854. #ifdef DEBUG_GAMEPAD_MAPPING
  1855. SDL_Log("Mapped RIGHTX to axis %d (ABS_RX)", out->rightx.target);
  1856. SDL_Log("Mapped RIGHTY to axis %d (ABS_RY)", out->righty.target);
  1857. #endif
  1858. } else if (joystick->hwdata->has_abs[ABS_Z] && joystick->hwdata->has_abs[ABS_RZ]) {
  1859. /* Android convention */
  1860. out->rightx.kind = EMappingKind_Axis;
  1861. out->righty.kind = EMappingKind_Axis;
  1862. out->rightx.target = joystick->hwdata->abs_map[ABS_Z];
  1863. out->righty.target = joystick->hwdata->abs_map[ABS_RZ];
  1864. #ifdef DEBUG_GAMEPAD_MAPPING
  1865. SDL_Log("Mapped RIGHTX to axis %d (ABS_Z)", out->rightx.target);
  1866. SDL_Log("Mapped RIGHTY to axis %d (ABS_RZ)", out->righty.target);
  1867. #endif
  1868. }
  1869. if (SDL_JoystickGetVendor(joystick) == USB_VENDOR_MICROSOFT) {
  1870. /* The Xbox Elite controllers have the paddles as BTN_TRIGGER_HAPPY5 - BTN_TRIGGER_HAPPY8 */
  1871. if (joystick->hwdata->has_key[BTN_TRIGGER_HAPPY5] &&
  1872. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY6] &&
  1873. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY7] &&
  1874. joystick->hwdata->has_key[BTN_TRIGGER_HAPPY8]) {
  1875. out->paddle1.kind = EMappingKind_Button;
  1876. out->paddle1.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY5];
  1877. out->paddle2.kind = EMappingKind_Button;
  1878. out->paddle2.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY7];
  1879. out->paddle3.kind = EMappingKind_Button;
  1880. out->paddle3.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY6];
  1881. out->paddle4.kind = EMappingKind_Button;
  1882. out->paddle4.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY8];
  1883. #ifdef DEBUG_GAMEPAD_MAPPING
  1884. SDL_Log("Mapped PADDLE1 to button %d (BTN_TRIGGER_HAPPY5)", out->paddle1.target);
  1885. SDL_Log("Mapped PADDLE2 to button %d (BTN_TRIGGER_HAPPY7)", out->paddle2.target);
  1886. SDL_Log("Mapped PADDLE3 to button %d (BTN_TRIGGER_HAPPY6)", out->paddle3.target);
  1887. SDL_Log("Mapped PADDLE4 to button %d (BTN_TRIGGER_HAPPY8)", out->paddle4.target);
  1888. #endif
  1889. }
  1890. /* The Xbox Series X controllers have the Share button as KEY_RECORD */
  1891. if (joystick->hwdata->has_key[KEY_RECORD]) {
  1892. out->misc1.kind = EMappingKind_Button;
  1893. out->misc1.target = joystick->hwdata->key_map[KEY_RECORD];
  1894. #ifdef DEBUG_GAMEPAD_MAPPING
  1895. SDL_Log("Mapped MISC1 to button %d (KEY_RECORD)", out->misc1.target);
  1896. #endif
  1897. }
  1898. }
  1899. LINUX_JoystickClose(joystick);
  1900. SDL_free(joystick);
  1901. /* Cache the mapping for later */
  1902. item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping));
  1903. if (item->mapping) {
  1904. SDL_memcpy(item->mapping, out, sizeof(*out));
  1905. }
  1906. #ifdef DEBUG_GAMEPAD_MAPPING
  1907. SDL_Log("Generated mapping for device %d", device_index);
  1908. #endif
  1909. return SDL_TRUE;
  1910. }
  1911. SDL_JoystickDriver SDL_LINUX_JoystickDriver = {
  1912. LINUX_JoystickInit,
  1913. LINUX_JoystickGetCount,
  1914. LINUX_JoystickDetect,
  1915. LINUX_JoystickGetDeviceName,
  1916. LINUX_JoystickGetDevicePath,
  1917. LINUX_JoystickGetDevicePlayerIndex,
  1918. LINUX_JoystickSetDevicePlayerIndex,
  1919. LINUX_JoystickGetDeviceGUID,
  1920. LINUX_JoystickGetDeviceInstanceID,
  1921. LINUX_JoystickOpen,
  1922. LINUX_JoystickRumble,
  1923. LINUX_JoystickRumbleTriggers,
  1924. LINUX_JoystickGetCapabilities,
  1925. LINUX_JoystickSetLED,
  1926. LINUX_JoystickSendEffect,
  1927. LINUX_JoystickSetSensorsEnabled,
  1928. LINUX_JoystickUpdate,
  1929. LINUX_JoystickClose,
  1930. LINUX_JoystickQuit,
  1931. LINUX_JoystickGetGamepadMapping
  1932. };
  1933. #endif /* SDL_JOYSTICK_LINUX */
  1934. /* vi: set ts=4 sw=4 expandtab: */