SDL  2.0
SDL_sysjoystick.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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 #ifdef __OpenBSD__
84 
85 #define HUG_DPAD_UP 0x90
86 #define HUG_DPAD_DOWN 0x91
87 #define HUG_DPAD_RIGHT 0x92
88 #define HUG_DPAD_LEFT 0x93
89 
90 #define HAT_CENTERED 0x00
91 #define HAT_UP 0x01
92 #define HAT_RIGHT 0x02
93 #define HAT_DOWN 0x04
94 #define HAT_LEFT 0x08
95 #define HAT_RIGHTUP (HAT_RIGHT|HAT_UP)
96 #define HAT_RIGHTDOWN (HAT_RIGHT|HAT_DOWN)
97 #define HAT_LEFTUP (HAT_LEFT|HAT_UP)
98 #define HAT_LEFTDOWN (HAT_LEFT|HAT_DOWN)
99 
100 /* calculate the value from the state of the dpad */
101 int
102 dpad_to_sdl(Sint32 *dpad)
103 {
104  if (dpad[2]) {
105  if (dpad[0])
106  return HAT_RIGHTUP;
107  else if (dpad[1])
108  return HAT_RIGHTDOWN;
109  else
110  return HAT_RIGHT;
111  } else if (dpad[3]) {
112  if (dpad[0])
113  return HAT_LEFTUP;
114  else if (dpad[1])
115  return HAT_LEFTDOWN;
116  else
117  return HAT_LEFT;
118  } else if (dpad[0]) {
119  return HAT_UP;
120  } else if (dpad[1]) {
121  return HAT_DOWN;
122  }
123  return HAT_CENTERED;
124 }
125 #endif
126 
127 struct report
128 {
129 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
130  void *buf; /* Buffer */
131 #elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
132  struct usb_gen_descriptor *buf; /* Buffer */
133 #else
134  struct usb_ctl_report *buf; /* Buffer */
135 #endif
136  size_t size; /* Buffer size */
137  int rid; /* Report ID */
138  enum
139  {
140  SREPORT_UNINIT,
141  SREPORT_CLEAN,
142  SREPORT_DIRTY
143  } status;
144 };
145 
146 static struct
147 {
148  int uhid_report;
149  hid_kind_t kind;
150  const char *name;
151 } const repinfo[] = {
152  {UHID_INPUT_REPORT, hid_input, "input"},
153  {UHID_OUTPUT_REPORT, hid_output, "output"},
154  {UHID_FEATURE_REPORT, hid_feature, "feature"}
155 };
156 
157 enum
158 {
159  REPORT_INPUT = 0,
160  REPORT_OUTPUT = 1,
161  REPORT_FEATURE = 2
162 };
163 
164 enum
165 {
166  JOYAXE_X,
167  JOYAXE_Y,
168  JOYAXE_Z,
169  JOYAXE_SLIDER,
170  JOYAXE_WHEEL,
171  JOYAXE_RX,
172  JOYAXE_RY,
173  JOYAXE_RZ,
174  JOYAXE_count
175 };
176 
177 struct joystick_hwdata
178 {
179  int fd;
180  char *path;
181  enum
182  {
183  BSDJOY_UHID, /* uhid(4) */
184  BSDJOY_JOY /* joy(4) */
185  } type;
186  struct report_desc *repdesc;
187  struct report inreport;
188  int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */
189 };
190 
191 static char *joynames[MAX_JOYS];
192 static char *joydevnames[MAX_JOYS];
193 
194 static int report_alloc(struct report *, struct report_desc *, int);
195 static void report_free(struct report *);
196 
197 #if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063)
198 #define REP_BUF_DATA(rep) ((rep)->buf->ucr_data)
199 #elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000))
200 #define REP_BUF_DATA(rep) ((rep)->buf)
201 #elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063))
202 #define REP_BUF_DATA(rep) ((rep)->buf->ugd_data)
203 #else
204 #define REP_BUF_DATA(rep) ((rep)->buf->data)
205 #endif
206 
207 static int numjoysticks = 0;
208 
209 static int BSD_JoystickOpen(SDL_Joystick * joy, int device_index);
210 static void BSD_JoystickClose(SDL_Joystick * joy);
211 
212 static int
213 BSD_JoystickInit(void)
214 {
215  char s[16];
216  int i, fd;
217 
218  numjoysticks = 0;
219 
220  SDL_memset(joynames, 0, sizeof(joynames));
221  SDL_memset(joydevnames, 0, sizeof(joydevnames));
222 
223  for (i = 0; i < MAX_UHID_JOYS; i++) {
224  SDL_Joystick nj;
225 
226  SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
227 
228  joynames[numjoysticks] = SDL_strdup(s);
229 
230  if (BSD_JoystickOpen(&nj, numjoysticks) == 0) {
231  BSD_JoystickClose(&nj);
232  numjoysticks++;
233  } else {
234  SDL_free(joynames[numjoysticks]);
235  joynames[numjoysticks] = NULL;
236  }
237  }
238  for (i = 0; i < MAX_JOY_JOYS; i++) {
239  SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
240  fd = open(s, O_RDONLY);
241  if (fd != -1) {
242  joynames[numjoysticks++] = SDL_strdup(s);
243  close(fd);
244  }
245  }
246 
247  /* Read the default USB HID usage table. */
248  hid_init(NULL);
249 
250  return (numjoysticks);
251 }
252 
253 static int
254 BSD_JoystickGetCount(void)
255 {
256  return numjoysticks;
257 }
258 
259 static void
260 BSD_JoystickDetect(void)
261 {
262 }
263 
264 static const char *
265 BSD_JoystickGetDeviceName(int device_index)
266 {
267  if (joydevnames[device_index] != NULL) {
268  return (joydevnames[device_index]);
269  }
270  return (joynames[device_index]);
271 }
272 
273 static int
274 BSD_JoystickGetDevicePlayerIndex(int device_index)
275 {
276  return -1;
277 }
278 
279 static void
280 BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index)
281 {
282 }
283 
284 /* Function to perform the mapping from device index to the instance id for this index */
285 static SDL_JoystickID
286 BSD_JoystickGetDeviceInstanceID(int device_index)
287 {
288  return device_index;
289 }
290 
291 static int
292 usage_to_joyaxe(unsigned usage)
293 {
294  int joyaxe;
295  switch (usage) {
296  case HUG_X:
297  joyaxe = JOYAXE_X;
298  break;
299  case HUG_Y:
300  joyaxe = JOYAXE_Y;
301  break;
302  case HUG_Z:
303  joyaxe = JOYAXE_Z;
304  break;
305  case HUG_SLIDER:
306  joyaxe = JOYAXE_SLIDER;
307  break;
308  case HUG_WHEEL:
309  joyaxe = JOYAXE_WHEEL;
310  break;
311  case HUG_RX:
312  joyaxe = JOYAXE_RX;
313  break;
314  case HUG_RY:
315  joyaxe = JOYAXE_RY;
316  break;
317  case HUG_RZ:
318  joyaxe = JOYAXE_RZ;
319  break;
320  default:
321  joyaxe = -1;
322  }
323  return joyaxe;
324 }
325 
326 static unsigned
327 hatval_to_sdl(Sint32 hatval)
328 {
329  static const unsigned hat_dir_map[8] = {
332  };
333  unsigned result;
334  if ((hatval & 7) == hatval)
335  result = hat_dir_map[hatval];
336  else
338  return result;
339 }
340 
341 
342 static int
343 BSD_JoystickOpen(SDL_Joystick * joy, int device_index)
344 {
345  char *path = joynames[device_index];
346  struct joystick_hwdata *hw;
347  struct hid_item hitem;
348  struct hid_data *hdata;
349  struct report *rep = NULL;
350 #if defined(__NetBSD__)
351  usb_device_descriptor_t udd;
352  struct usb_string_desc usd;
353 #endif
354  int fd;
355  int i;
356 
357  fd = open(path, O_RDONLY);
358  if (fd == -1) {
359  return SDL_SetError("%s: %s", path, strerror(errno));
360  }
361 
362  joy->instance_id = device_index;
363  hw = (struct joystick_hwdata *)
364  SDL_malloc(sizeof(struct joystick_hwdata));
365  if (hw == NULL) {
366  close(fd);
367  return SDL_OutOfMemory();
368  }
369  joy->hwdata = hw;
370  hw->fd = fd;
371  hw->path = SDL_strdup(path);
372  if (!SDL_strncmp(path, "/dev/joy", 8)) {
373  hw->type = BSDJOY_JOY;
374  joy->naxes = 2;
375  joy->nbuttons = 2;
376  joy->nhats = 0;
377  joy->nballs = 0;
378  joydevnames[device_index] = SDL_strdup("Gameport joystick");
379  goto usbend;
380  } else {
381  hw->type = BSDJOY_UHID;
382  }
383 
384  {
385  int ax;
386  for (ax = 0; ax < JOYAXE_count; ax++)
387  hw->axis_map[ax] = -1;
388  }
389  hw->repdesc = hid_get_report_desc(fd);
390  if (hw->repdesc == NULL) {
391  SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
392  strerror(errno));
393  goto usberr;
394  }
395  rep = &hw->inreport;
396 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
397  rep->rid = hid_get_report_id(fd);
398  if (rep->rid < 0) {
399 #else
400  if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
401 #endif
402  rep->rid = -1; /* XXX */
403  }
404 #if defined(__NetBSD__)
405  if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1)
406  goto desc_failed;
407 
408  /* Get default language */
409  usd.usd_string_index = USB_LANGUAGE_TABLE;
410  usd.usd_language_id = 0;
411  if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) {
412  usd.usd_language_id = 0;
413  } else {
414  usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
415  }
416 
417  usd.usd_string_index = udd.iProduct;
418  if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
419  char str[128];
420  char *new_name = NULL;
421  int i;
422  for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) {
423  str[i] = UGETW(usd.usd_desc.bString[i]);
424  }
425  str[i] = '\0';
426  asprintf(&new_name, "%s @ %s", str, path);
427  if (new_name != NULL) {
428  SDL_free(joydevnames[numjoysticks]);
429  joydevnames[numjoysticks] = new_name;
430  }
431  }
432 desc_failed:
433 #endif
434  if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
435  goto usberr;
436  }
437  if (rep->size <= 0) {
438  SDL_SetError("%s: Input report descriptor has invalid length",
439  hw->path);
440  goto usberr;
441  }
442 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
443  hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
444 #else
445  hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
446 #endif
447  if (hdata == NULL) {
448  SDL_SetError("%s: Cannot start HID parser", hw->path);
449  goto usberr;
450  }
451  joy->naxes = 0;
452  joy->nbuttons = 0;
453  joy->nhats = 0;
454  joy->nballs = 0;
455  for (i = 0; i < JOYAXE_count; i++)
456  hw->axis_map[i] = -1;
457 
458  while (hid_get_item(hdata, &hitem) > 0) {
459  char *sp;
460  const char *s;
461 
462  switch (hitem.kind) {
463  case hid_collection:
464  switch (HID_PAGE(hitem.usage)) {
465  case HUP_GENERIC_DESKTOP:
466  switch (HID_USAGE(hitem.usage)) {
467  case HUG_JOYSTICK:
468  case HUG_GAME_PAD:
469  s = hid_usage_in_page(hitem.usage);
470  sp = SDL_malloc(SDL_strlen(s) + 5);
471  SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)",
472  s, device_index);
473  joydevnames[device_index] = sp;
474  }
475  }
476  break;
477  case hid_input:
478  switch (HID_PAGE(hitem.usage)) {
479  case HUP_GENERIC_DESKTOP:
480  {
481  unsigned usage = HID_USAGE(hitem.usage);
482  int joyaxe = usage_to_joyaxe(usage);
483  if (joyaxe >= 0) {
484  hw->axis_map[joyaxe] = 1;
485  } else if (usage == HUG_HAT_SWITCH
486 #ifdef __OpenBSD__
487  || usage == HUG_DPAD_UP
488 #endif
489  ) {
490  joy->nhats++;
491  }
492  break;
493  }
494  case HUP_BUTTON:
495  joy->nbuttons++;
496  break;
497  default:
498  break;
499  }
500  break;
501  default:
502  break;
503  }
504  }
505  hid_end_parse(hdata);
506  for (i = 0; i < JOYAXE_count; i++)
507  if (hw->axis_map[i] > 0)
508  hw->axis_map[i] = joy->naxes++;
509 
510  if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) {
511  SDL_SetError("%s: Not a joystick, ignoring", hw->path);
512  goto usberr;
513  }
514 
515  usbend:
516  /* The poll blocks the event thread. */
517  fcntl(fd, F_SETFL, O_NONBLOCK);
518 #ifdef __NetBSD__
519  /* Flush pending events */
520  if (rep) {
521  while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size)
522  ;
523  }
524 #endif
525 
526  return (0);
527  usberr:
528  close(hw->fd);
529  SDL_free(hw->path);
530  SDL_free(hw);
531  return (-1);
532 }
533 
534 static void
535 BSD_JoystickUpdate(SDL_Joystick * joy)
536 {
537  struct hid_item hitem;
538  struct hid_data *hdata;
539  struct report *rep;
540  int nbutton, naxe = -1;
541  Sint32 v;
542 #ifdef __OpenBSD__
543  Sint32 dpad[4] = {0, 0, 0, 0};
544 #endif
545 
546 #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
547  struct joystick gameport;
548  static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
549 
550  if (joy->hwdata->type == BSDJOY_JOY) {
551  while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
552  if (abs(x - gameport.x) > 8) {
553  x = gameport.x;
554  if (x < xmin) {
555  xmin = x;
556  }
557  if (x > xmax) {
558  xmax = x;
559  }
560  if (xmin == xmax) {
561  xmin--;
562  xmax++;
563  }
564  v = (Sint32) x;
565  v -= (xmax + xmin + 1) / 2;
566  v *= 32768 / ((xmax - xmin + 1) / 2);
567  SDL_PrivateJoystickAxis(joy, 0, v);
568  }
569  if (abs(y - gameport.y) > 8) {
570  y = gameport.y;
571  if (y < ymin) {
572  ymin = y;
573  }
574  if (y > ymax) {
575  ymax = y;
576  }
577  if (ymin == ymax) {
578  ymin--;
579  ymax++;
580  }
581  v = (Sint32) y;
582  v -= (ymax + ymin + 1) / 2;
583  v *= 32768 / ((ymax - ymin + 1) / 2);
584  SDL_PrivateJoystickAxis(joy, 1, v);
585  }
586  SDL_PrivateJoystickButton(joy, 0, gameport.b1);
587  SDL_PrivateJoystickButton(joy, 1, gameport.b2);
588  }
589  return;
590  }
591 #endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
592 
593  rep = &joy->hwdata->inreport;
594 
595  while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
596 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
597  hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
598 #else
599  hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
600 #endif
601  if (hdata == NULL) {
602  /*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/
603  continue;
604  }
605 
606  for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
607  switch (hitem.kind) {
608  case hid_input:
609  switch (HID_PAGE(hitem.usage)) {
610  case HUP_GENERIC_DESKTOP:
611  {
612  unsigned usage = HID_USAGE(hitem.usage);
613  int joyaxe = usage_to_joyaxe(usage);
614  if (joyaxe >= 0) {
615  naxe = joy->hwdata->axis_map[joyaxe];
616  /* scaleaxe */
617  v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
618  v -= (hitem.logical_maximum +
619  hitem.logical_minimum + 1) / 2;
620  v *= 32768 /
621  ((hitem.logical_maximum -
622  hitem.logical_minimum + 1) / 2);
623  SDL_PrivateJoystickAxis(joy, naxe, v);
624  } else if (usage == HUG_HAT_SWITCH) {
625  v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
626  SDL_PrivateJoystickHat(joy, 0,
627  hatval_to_sdl(v) -
628  hitem.logical_minimum);
629  }
630 #ifdef __OpenBSD__
631  else if (usage == HUG_DPAD_UP) {
632  dpad[0] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
633  SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
634  }
635  else if (usage == HUG_DPAD_DOWN) {
636  dpad[1] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
637  SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
638  }
639  else if (usage == HUG_DPAD_RIGHT) {
640  dpad[2] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
641  SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
642  }
643  else if (usage == HUG_DPAD_LEFT) {
644  dpad[3] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
645  SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
646  }
647 #endif
648  break;
649  }
650  case HUP_BUTTON:
651  v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
652  SDL_PrivateJoystickButton(joy, nbutton, v);
653  nbutton++;
654  break;
655  default:
656  continue;
657  }
658  break;
659  default:
660  break;
661  }
662  }
663  hid_end_parse(hdata);
664  }
665 }
666 
667 /* Function to close a joystick after use */
668 static void
669 BSD_JoystickClose(SDL_Joystick * joy)
670 {
671  if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
672  report_free(&joy->hwdata->inreport);
673  hid_dispose_report_desc(joy->hwdata->repdesc);
674  }
675  close(joy->hwdata->fd);
676  SDL_free(joy->hwdata->path);
677  SDL_free(joy->hwdata);
678 }
679 
680 static void
681 BSD_JoystickQuit(void)
682 {
683  int i;
684 
685  for (i = 0; i < MAX_JOYS; i++) {
686  SDL_free(joynames[i]);
687  SDL_free(joydevnames[i]);
688  }
689 
690  return;
691 }
692 
693 static SDL_JoystickGUID
694 BSD_JoystickGetDeviceGUID( int device_index )
695 {
696  SDL_JoystickGUID guid;
697  /* the GUID is just the first 16 chars of the name for now */
698  const char *name = BSD_JoystickGetDeviceName( device_index );
699  SDL_zero( guid );
700  SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
701  return guid;
702 }
703 
704 static int
705 report_alloc(struct report *r, struct report_desc *rd, int repind)
706 {
707  int len;
708 
709 #ifdef __DragonFly__
710  len = hid_report_size(rd, r->rid, repinfo[repind].kind);
711 #elif __FREEBSD__
712 # if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
713 # if (__FreeBSD_kernel_version <= 500111)
714  len = hid_report_size(rd, r->rid, repinfo[repind].kind);
715 # else
716  len = hid_report_size(rd, repinfo[repind].kind, r->rid);
717 # endif
718 # else
719  len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
720 # endif
721 #else
722 # ifdef USBHID_NEW
723  len = hid_report_size(rd, repinfo[repind].kind, r->rid);
724 # else
725  len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
726 # endif
727 #endif
728 
729  if (len < 0) {
730  return SDL_SetError("Negative HID report size");
731  }
732  r->size = len;
733 
734  if (r->size > 0) {
735 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
736  r->buf = SDL_malloc(r->size);
737 #else
738  r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
739  r->size);
740 #endif
741  if (r->buf == NULL) {
742  return SDL_OutOfMemory();
743  }
744  } else {
745  r->buf = NULL;
746  }
747 
748  r->status = SREPORT_CLEAN;
749  return 0;
750 }
751 
752 static void
753 report_free(struct report *r)
754 {
755  SDL_free(r->buf);
756  r->status = SREPORT_UNINIT;
757 }
758 
759 static int
760 BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
761 {
762  return SDL_Unsupported();
763 }
764 
765 SDL_JoystickDriver SDL_BSD_JoystickDriver =
766 {
767  BSD_JoystickInit,
768  BSD_JoystickGetCount,
769  BSD_JoystickDetect,
770  BSD_JoystickGetDeviceName,
771  BSD_JoystickGetDevicePlayerIndex,
772  BSD_JoystickSetDevicePlayerIndex,
773  BSD_JoystickGetDeviceGUID,
774  BSD_JoystickGetDeviceInstanceID,
775  BSD_JoystickOpen,
776  BSD_JoystickRumble,
777  BSD_JoystickUpdate,
778  BSD_JoystickClose,
779  BSD_JoystickQuit,
780 };
781 
782 #endif /* SDL_JOYSTICK_USBHID */
783 
784 /* vi: set ts=4 sw=4 expandtab: */
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:418
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
joystick_hwdata::nhats
int nhats
Definition: SDL_sysjoystick_c.h:48
Sint32
int32_t Sint32
Definition: SDL_stdinc.h:197
numjoysticks
static int numjoysticks
Definition: SDL_sysjoystick.m:83
SDL_HAT_CENTERED
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:339
NULL
#define NULL
Definition: begin_code.h:167
SDL_HAT_DOWN
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:342
endif
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
Definition: pixman-arm-neon-asm.h:549
SDL_joystick.h
SDL_BSD_JoystickDriver
SDL_JoystickDriver SDL_BSD_JoystickDriver
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
hid_init
int HID_API_EXPORT HID_API_CALL hid_init(void)
Initialize the HIDAPI library.
path
GLsizei const GLchar *const * path
Definition: SDL_opengl_glext.h:3733
SDL_strncmp
#define SDL_strncmp
Definition: SDL_dynapi_overrides.h:418
v
const GLdouble * v
Definition: SDL_opengl.h:2064
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
SDL_HAT_LEFTDOWN
#define SDL_HAT_LEFTDOWN
Definition: SDL_joystick.h:347
SDL_PrivateJoystickAxis
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:1023
SDL_JoystickID
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2929
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: SDL_opengl_glext.h:2483
joystick_hwdata::fd
int fd
Definition: SDL_sysjoystick_c.h:32
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
usage
GLsizeiptr const void GLenum usage
Definition: SDL_opengl_glext.h:540
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
joystick_hwdata::naxes
int naxes
Definition: SDL_sysjoystick_c.h:46
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:663
SDL_PrivateJoystickButton
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:1162
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_HAT_LEFT
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:343
SDL_min
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
SDL_HAT_LEFTUP
#define SDL_HAT_LEFTUP
Definition: SDL_joystick.h:346
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_PrivateJoystickHat
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:1086
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_HAT_RIGHT
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:341
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
s
GLdouble s
Definition: SDL_opengl.h:2063
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:40
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_strlen
#define SDL_strlen
Definition: SDL_dynapi_overrides.h:393
SDL_HAT_UP
#define SDL_HAT_UP
Definition: SDL_joystick.h:340
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
fd
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
SDL_JoystickGUID
Definition: SDL_joystick.h:70
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
SDL_HAT_RIGHTDOWN
#define SDL_HAT_RIGHTDOWN
Definition: SDL_joystick.h:345
i
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
SDL_HAT_RIGHTUP
#define SDL_HAT_RIGHTUP
Definition: SDL_joystick.h:344
joystick_hwdata
Definition: SDL_sysjoystick_c.h:46