SDL  2.0
SDL_sysjoystick.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #ifdef SDL_JOYSTICK_USBHID
24 
25 /*
26  * Joystick driver for the uhid(4) interface found in OpenBSD,
27  * NetBSD and FreeBSD.
28  *
29  * Maintainer: <vedge at csoft.org>
30  */
31 
32 #include <sys/param.h>
33 
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <errno.h>
37 
38 #ifndef __FreeBSD_kernel_version
39 #define __FreeBSD_kernel_version __FreeBSD_version
40 #endif
41 
42 #if defined(HAVE_USB_H)
43 #include <usb.h>
44 #endif
45 #ifdef __DragonFly__
46 #include <bus/usb/usb.h>
47 #include <bus/usb/usbhid.h>
48 #else
49 #include <dev/usb/usb.h>
50 #include <dev/usb/usbhid.h>
51 #endif
52 
53 #if defined(HAVE_USBHID_H)
54 #include <usbhid.h>
55 #elif defined(HAVE_LIBUSB_H)
56 #include <libusb.h>
57 #elif defined(HAVE_LIBUSBHID_H)
58 #include <libusbhid.h>
59 #endif
60 
61 #if defined(__FREEBSD__) || defined(__FreeBSD_kernel__)
62 #ifndef __DragonFly__
63 #include <osreldate.h>
64 #endif
65 #if __FreeBSD_kernel_version > 800063
66 #include <dev/usb/usb_ioctl.h>
67 #endif
68 #include <sys/joystick.h>
69 #endif
70 
71 #if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
72 #include <machine/joystick.h>
73 #endif
74 
75 #include "SDL_joystick.h"
76 #include "../SDL_sysjoystick.h"
77 #include "../SDL_joystick_c.h"
78 
79 #define MAX_UHID_JOYS 64
80 #define MAX_JOY_JOYS 2
81 #define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS)
82 
83 
84 struct report
85 {
86 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
87  void *buf; /* Buffer */
88 #elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
89  struct usb_gen_descriptor *buf; /* Buffer */
90 #else
91  struct usb_ctl_report *buf; /* Buffer */
92 #endif
93  size_t size; /* Buffer size */
94  int rid; /* Report ID */
95  enum
96  {
97  SREPORT_UNINIT,
98  SREPORT_CLEAN,
99  SREPORT_DIRTY
100  } status;
101 };
102 
103 static struct
104 {
105  int uhid_report;
106  hid_kind_t kind;
107  const char *name;
108 } const repinfo[] = {
109  {UHID_INPUT_REPORT, hid_input, "input"},
110  {UHID_OUTPUT_REPORT, hid_output, "output"},
111  {UHID_FEATURE_REPORT, hid_feature, "feature"}
112 };
113 
114 enum
115 {
116  REPORT_INPUT = 0,
117  REPORT_OUTPUT = 1,
118  REPORT_FEATURE = 2
119 };
120 
121 enum
122 {
123  JOYAXE_X,
124  JOYAXE_Y,
125  JOYAXE_Z,
126  JOYAXE_SLIDER,
127  JOYAXE_WHEEL,
128  JOYAXE_RX,
129  JOYAXE_RY,
130  JOYAXE_RZ,
131  JOYAXE_count
132 };
133 
134 struct joystick_hwdata
135 {
136  int fd;
137  char *path;
138  enum
139  {
140  BSDJOY_UHID, /* uhid(4) */
141  BSDJOY_JOY /* joy(4) */
142  } type;
143  struct report_desc *repdesc;
144  struct report inreport;
145  int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */
146 };
147 
148 static char *joynames[MAX_JOYS];
149 static char *joydevnames[MAX_JOYS];
150 
151 static int report_alloc(struct report *, struct report_desc *, int);
152 static void report_free(struct report *);
153 
154 #if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063)
155 #define REP_BUF_DATA(rep) ((rep)->buf->ucr_data)
156 #elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000))
157 #define REP_BUF_DATA(rep) ((rep)->buf)
158 #elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063))
159 #define REP_BUF_DATA(rep) ((rep)->buf->ugd_data)
160 #else
161 #define REP_BUF_DATA(rep) ((rep)->buf->data)
162 #endif
163 
164 static int SDL_SYS_numjoysticks = 0;
165 
166 int
168 {
169  char s[16];
170  int i, fd;
171 
172  SDL_SYS_numjoysticks = 0;
173 
174  SDL_memset(joynames, 0, sizeof(joynames));
175  SDL_memset(joydevnames, 0, sizeof(joydevnames));
176 
177  for (i = 0; i < MAX_UHID_JOYS; i++) {
178  SDL_Joystick nj;
179 
180  SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
181 
182  joynames[SDL_SYS_numjoysticks] = SDL_strdup(s);
183 
184  if (SDL_SYS_JoystickOpen(&nj, SDL_SYS_numjoysticks) == 0) {
186  SDL_SYS_numjoysticks++;
187  } else {
188  SDL_free(joynames[SDL_SYS_numjoysticks]);
189  joynames[SDL_SYS_numjoysticks] = NULL;
190  }
191  }
192  for (i = 0; i < MAX_JOY_JOYS; i++) {
193  SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
194  fd = open(s, O_RDONLY);
195  if (fd != -1) {
196  joynames[SDL_SYS_numjoysticks++] = SDL_strdup(s);
197  close(fd);
198  }
199  }
200 
201  /* Read the default USB HID usage table. */
202  hid_init(NULL);
203 
204  return (SDL_SYS_numjoysticks);
205 }
206 
207 int
209 {
210  return SDL_SYS_numjoysticks;
211 }
212 
213 void
215 {
216 }
217 
218 const char *
219 SDL_SYS_JoystickNameForDeviceIndex(int device_index)
220 {
221  if (joydevnames[device_index] != NULL) {
222  return (joydevnames[device_index]);
223  }
224  return (joynames[device_index]);
225 }
226 
227 /* Function to perform the mapping from device index to the instance id for this index */
229 {
230  return device_index;
231 }
232 
233 static int
234 usage_to_joyaxe(unsigned usage)
235 {
236  int joyaxe;
237  switch (usage) {
238  case HUG_X:
239  joyaxe = JOYAXE_X;
240  break;
241  case HUG_Y:
242  joyaxe = JOYAXE_Y;
243  break;
244  case HUG_Z:
245  joyaxe = JOYAXE_Z;
246  break;
247  case HUG_SLIDER:
248  joyaxe = JOYAXE_SLIDER;
249  break;
250  case HUG_WHEEL:
251  joyaxe = JOYAXE_WHEEL;
252  break;
253  case HUG_RX:
254  joyaxe = JOYAXE_RX;
255  break;
256  case HUG_RY:
257  joyaxe = JOYAXE_RY;
258  break;
259  case HUG_RZ:
260  joyaxe = JOYAXE_RZ;
261  break;
262  default:
263  joyaxe = -1;
264  }
265  return joyaxe;
266 }
267 
268 static unsigned
269 hatval_to_sdl(Sint32 hatval)
270 {
271  static const unsigned hat_dir_map[8] = {
274  };
275  unsigned result;
276  if ((hatval & 7) == hatval)
277  result = hat_dir_map[hatval];
278  else
279  result = SDL_HAT_CENTERED;
280  return result;
281 }
282 
283 
284 int
285 SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index)
286 {
287  char *path = joynames[device_index];
288  struct joystick_hwdata *hw;
289  struct hid_item hitem;
290  struct hid_data *hdata;
291  struct report *rep = NULL;
292  int fd;
293  int i;
294 
295  fd = open(path, O_RDONLY);
296  if (fd == -1) {
297  return SDL_SetError("%s: %s", path, strerror(errno));
298  }
299 
300  joy->instance_id = device_index;
301  hw = (struct joystick_hwdata *)
302  SDL_malloc(sizeof(struct joystick_hwdata));
303  if (hw == NULL) {
304  close(fd);
305  return SDL_OutOfMemory();
306  }
307  joy->hwdata = hw;
308  hw->fd = fd;
309  hw->path = SDL_strdup(path);
310  if (!SDL_strncmp(path, "/dev/joy", 8)) {
311  hw->type = BSDJOY_JOY;
312  joy->naxes = 2;
313  joy->nbuttons = 2;
314  joy->nhats = 0;
315  joy->nballs = 0;
316  joydevnames[device_index] = SDL_strdup("Gameport joystick");
317  goto usbend;
318  } else {
319  hw->type = BSDJOY_UHID;
320  }
321 
322  {
323  int ax;
324  for (ax = 0; ax < JOYAXE_count; ax++)
325  hw->axis_map[ax] = -1;
326  }
327  hw->repdesc = hid_get_report_desc(fd);
328  if (hw->repdesc == NULL) {
329  SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
330  strerror(errno));
331  goto usberr;
332  }
333  rep = &hw->inreport;
334 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
335  rep->rid = hid_get_report_id(fd);
336  if (rep->rid < 0) {
337 #else
338  if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
339 #endif
340  rep->rid = -1; /* XXX */
341  }
342 #if defined(__NetBSD__)
343  usb_device_descriptor_t udd;
344  struct usb_string_desc usd;
345  if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1)
346  goto desc_failed;
347 
348  /* Get default language */
349  usd.usd_string_index = USB_LANGUAGE_TABLE;
350  usd.usd_language_id = 0;
351  if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) {
352  usd.usd_language_id = 0;
353  } else {
354  usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
355  }
356 
357  usd.usd_string_index = udd.iProduct;
358  if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
359  char str[128];
360  char *new_name = NULL;
361  int i;
362  for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) {
363  str[i] = UGETW(usd.usd_desc.bString[i]);
364  }
365  str[i] = '\0';
366  asprintf(&new_name, "%s @ %s", str, path);
367  if (new_name != NULL) {
368  SDL_free(joydevnames[SDL_SYS_numjoysticks]);
369  joydevnames[SDL_SYS_numjoysticks] = new_name;
370  }
371  }
372 desc_failed:
373 #endif
374  if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
375  goto usberr;
376  }
377  if (rep->size <= 0) {
378  SDL_SetError("%s: Input report descriptor has invalid length",
379  hw->path);
380  goto usberr;
381  }
382 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
383  hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
384 #else
385  hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
386 #endif
387  if (hdata == NULL) {
388  SDL_SetError("%s: Cannot start HID parser", hw->path);
389  goto usberr;
390  }
391  joy->naxes = 0;
392  joy->nbuttons = 0;
393  joy->nhats = 0;
394  joy->nballs = 0;
395  for (i = 0; i < JOYAXE_count; i++)
396  hw->axis_map[i] = -1;
397 
398  while (hid_get_item(hdata, &hitem) > 0) {
399  char *sp;
400  const char *s;
401 
402  switch (hitem.kind) {
403  case hid_collection:
404  switch (HID_PAGE(hitem.usage)) {
405  case HUP_GENERIC_DESKTOP:
406  switch (HID_USAGE(hitem.usage)) {
407  case HUG_JOYSTICK:
408  case HUG_GAME_PAD:
409  s = hid_usage_in_page(hitem.usage);
410  sp = SDL_malloc(SDL_strlen(s) + 5);
411  SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)",
412  s, device_index);
413  joydevnames[device_index] = sp;
414  }
415  }
416  break;
417  case hid_input:
418  switch (HID_PAGE(hitem.usage)) {
419  case HUP_GENERIC_DESKTOP:
420  {
421  unsigned usage = HID_USAGE(hitem.usage);
422  int joyaxe = usage_to_joyaxe(usage);
423  if (joyaxe >= 0) {
424  hw->axis_map[joyaxe] = 1;
425  } else if (usage == HUG_HAT_SWITCH) {
426  joy->nhats++;
427  }
428  break;
429  }
430  case HUP_BUTTON:
431  joy->nbuttons++;
432  break;
433  default:
434  break;
435  }
436  break;
437  default:
438  break;
439  }
440  }
441  hid_end_parse(hdata);
442  for (i = 0; i < JOYAXE_count; i++)
443  if (hw->axis_map[i] > 0)
444  hw->axis_map[i] = joy->naxes++;
445 
446  if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) {
447  SDL_SetError("%s: Not a joystick, ignoring", hw->path);
448  goto usberr;
449  }
450 
451  usbend:
452  /* The poll blocks the event thread. */
453  fcntl(fd, F_SETFL, O_NONBLOCK);
454 #ifdef __NetBSD__
455  /* Flush pending events */
456  if (rep) {
457  while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size)
458  ;
459  }
460 #endif
461 
462  return (0);
463  usberr:
464  close(hw->fd);
465  SDL_free(hw->path);
466  SDL_free(hw);
467  return (-1);
468 }
469 
470 /* Function to determine if this joystick is attached to the system right now */
471 SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
472 {
473  return SDL_TRUE;
474 }
475 
476 void
477 SDL_SYS_JoystickUpdate(SDL_Joystick * joy)
478 {
479  struct hid_item hitem;
480  struct hid_data *hdata;
481  struct report *rep;
482  int nbutton, naxe = -1;
483  Sint32 v;
484 
485 #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
486  struct joystick gameport;
487  static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
488 
489  if (joy->hwdata->type == BSDJOY_JOY) {
490  while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
491  if (abs(x - gameport.x) > 8) {
492  x = gameport.x;
493  if (x < xmin) {
494  xmin = x;
495  }
496  if (x > xmax) {
497  xmax = x;
498  }
499  if (xmin == xmax) {
500  xmin--;
501  xmax++;
502  }
503  v = (Sint32) x;
504  v -= (xmax + xmin + 1) / 2;
505  v *= 32768 / ((xmax - xmin + 1) / 2);
506  SDL_PrivateJoystickAxis(joy, 0, v);
507  }
508  if (abs(y - gameport.y) > 8) {
509  y = gameport.y;
510  if (y < ymin) {
511  ymin = y;
512  }
513  if (y > ymax) {
514  ymax = y;
515  }
516  if (ymin == ymax) {
517  ymin--;
518  ymax++;
519  }
520  v = (Sint32) y;
521  v -= (ymax + ymin + 1) / 2;
522  v *= 32768 / ((ymax - ymin + 1) / 2);
523  SDL_PrivateJoystickAxis(joy, 1, v);
524  }
525  SDL_PrivateJoystickButton(joy, 0, gameport.b1);
526  SDL_PrivateJoystickButton(joy, 1, gameport.b2);
527  }
528  return;
529  }
530 #endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
531 
532  rep = &joy->hwdata->inreport;
533 
534  while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
535 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
536  hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
537 #else
538  hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
539 #endif
540  if (hdata == NULL) {
541  /*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/
542  continue;
543  }
544 
545  for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
546  switch (hitem.kind) {
547  case hid_input:
548  switch (HID_PAGE(hitem.usage)) {
549  case HUP_GENERIC_DESKTOP:
550  {
551  unsigned usage = HID_USAGE(hitem.usage);
552  int joyaxe = usage_to_joyaxe(usage);
553  if (joyaxe >= 0) {
554  naxe = joy->hwdata->axis_map[joyaxe];
555  /* scaleaxe */
556  v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
557  v -= (hitem.logical_maximum +
558  hitem.logical_minimum + 1) / 2;
559  v *= 32768 /
560  ((hitem.logical_maximum -
561  hitem.logical_minimum + 1) / 2);
562  SDL_PrivateJoystickAxis(joy, naxe, v);
563  } else if (usage == HUG_HAT_SWITCH) {
564  v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
565  SDL_PrivateJoystickHat(joy, 0,
566  hatval_to_sdl(v) -
567  hitem.logical_minimum);
568  }
569  break;
570  }
571  case HUP_BUTTON:
572  v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
573  SDL_PrivateJoystickButton(joy, nbutton, v);
574  nbutton++;
575  break;
576  default:
577  continue;
578  }
579  break;
580  default:
581  break;
582  }
583  }
584  hid_end_parse(hdata);
585  }
586 }
587 
588 /* Function to close a joystick after use */
589 void
590 SDL_SYS_JoystickClose(SDL_Joystick * joy)
591 {
592  if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
593  report_free(&joy->hwdata->inreport);
594  hid_dispose_report_desc(joy->hwdata->repdesc);
595  }
596  close(joy->hwdata->fd);
597  SDL_free(joy->hwdata->path);
598  SDL_free(joy->hwdata);
599 }
600 
601 void
603 {
604  int i;
605 
606  for (i = 0; i < MAX_JOYS; i++) {
607  SDL_free(joynames[i]);
608  SDL_free(joydevnames[i]);
609  }
610 
611  return;
612 }
613 
615 {
616  SDL_JoystickGUID guid;
617  /* the GUID is just the first 16 chars of the name for now */
618  const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
619  SDL_zero( guid );
620  SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
621  return guid;
622 }
623 
624 SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
625 {
626  SDL_JoystickGUID guid;
627  /* the GUID is just the first 16 chars of the name for now */
628  const char *name = joystick->name;
629  SDL_zero( guid );
630  SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
631  return guid;
632 }
633 
634 static int
635 report_alloc(struct report *r, struct report_desc *rd, int repind)
636 {
637  int len;
638 
639 #ifdef __DragonFly__
640  len = hid_report_size(rd, r->rid, repinfo[repind].kind);
641 #elif __FREEBSD__
642 # if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
643 # if (__FreeBSD_kernel_version <= 500111)
644  len = hid_report_size(rd, r->rid, repinfo[repind].kind);
645 # else
646  len = hid_report_size(rd, repinfo[repind].kind, r->rid);
647 # endif
648 # else
649  len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
650 # endif
651 #else
652 # ifdef USBHID_NEW
653  len = hid_report_size(rd, repinfo[repind].kind, r->rid);
654 # else
655  len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
656 # endif
657 #endif
658 
659  if (len < 0) {
660  return SDL_SetError("Negative HID report size");
661  }
662  r->size = len;
663 
664  if (r->size > 0) {
665 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
666  r->buf = SDL_malloc(r->size);
667 #else
668  r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
669  r->size);
670 #endif
671  if (r->buf == NULL) {
672  return SDL_OutOfMemory();
673  }
674  } else {
675  r->buf = NULL;
676  }
677 
678  r->status = SREPORT_CLEAN;
679  return 0;
680 }
681 
682 static void
683 report_free(struct report *r)
684 {
685  SDL_free(r->buf);
686  r->status = SREPORT_UNINIT;
687 }
688 
689 #endif /* SDL_JOYSTICK_USBHID */
690 
691 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_HAT_LEFTDOWN
Definition: SDL_joystick.h:324
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
GLuint64EXT * result
GLdouble s
Definition: SDL_opengl.h:2063
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:712
const GLdouble * v
Definition: SDL_opengl.h:2064
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
#define SDL_HAT_RIGHTUP
Definition: SDL_joystick.h:321
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:788
void SDL_SYS_JoystickQuit(void)
#define SDL_strncmp
GLenum GLsizei len
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:655
GLuint const GLchar * name
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:318
#define SDL_memcpy
GLsizeiptr const void GLenum usage
#define SDL_HAT_RIGHTDOWN
Definition: SDL_joystick.h:322
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:320
#define SDL_free
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
int32_t Sint32
Definition: SDL_stdinc.h:175
GLenum GLuint GLenum GLsizei const GLchar * buf
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
GLsizeiptr size
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
int SDL_SYS_JoystickInit(void)
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
int SDL_SYS_NumJoysticks(void)
#define SDL_SetError
#define SDL_strlen
#define SDL_strdup
#define SDL_HAT_LEFTUP
Definition: SDL_joystick.h:323
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
#define SDL_snprintf
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
#define SDL_malloc
GLsizei const GLchar *const * path
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:316
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
#define SDL_HAT_UP
Definition: SDL_joystick.h:317
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:319
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
#define SDL_memset
void SDL_SYS_JoystickDetect(void)