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