SDL 2.0
SDL_sysjoystick.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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 */
101int
102dpad_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
127struct 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
146static 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
157enum
158{
159 REPORT_INPUT = 0,
160 REPORT_OUTPUT = 1,
161 REPORT_FEATURE = 2
162};
163
164enum
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
177struct 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
191static char *joynames[MAX_JOYS];
192static char *joydevnames[MAX_JOYS];
193
194static int report_alloc(struct report *, struct report_desc *, int);
195static 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
207static int numjoysticks = 0;
208
209static int BSD_JoystickOpen(SDL_Joystick * joy, int device_index);
210static void BSD_JoystickClose(SDL_Joystick * joy);
211
212static int
213BSD_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
253static int
254BSD_JoystickGetCount(void)
255{
256 return numjoysticks;
257}
258
259static void
260BSD_JoystickDetect(void)
261{
262}
263
264static const char *
265BSD_JoystickGetDeviceName(int device_index)
266{
267 if (joydevnames[device_index] != NULL) {
268 return (joydevnames[device_index]);
269 }
270 return (joynames[device_index]);
271}
272
273static int
274BSD_JoystickGetDevicePlayerIndex(int device_index)
275{
276 return -1;
277}
278
279/* Function to perform the mapping from device index to the instance id for this index */
280static SDL_JoystickID
281BSD_JoystickGetDeviceInstanceID(int device_index)
282{
283 return device_index;
284}
285
286static int
287usage_to_joyaxe(unsigned usage)
288{
289 int joyaxe;
290 switch (usage) {
291 case HUG_X:
292 joyaxe = JOYAXE_X;
293 break;
294 case HUG_Y:
295 joyaxe = JOYAXE_Y;
296 break;
297 case HUG_Z:
298 joyaxe = JOYAXE_Z;
299 break;
300 case HUG_SLIDER:
301 joyaxe = JOYAXE_SLIDER;
302 break;
303 case HUG_WHEEL:
304 joyaxe = JOYAXE_WHEEL;
305 break;
306 case HUG_RX:
307 joyaxe = JOYAXE_RX;
308 break;
309 case HUG_RY:
310 joyaxe = JOYAXE_RY;
311 break;
312 case HUG_RZ:
313 joyaxe = JOYAXE_RZ;
314 break;
315 default:
316 joyaxe = -1;
317 }
318 return joyaxe;
319}
320
321static unsigned
322hatval_to_sdl(Sint32 hatval)
323{
324 static const unsigned hat_dir_map[8] = {
327 };
328 unsigned result;
329 if ((hatval & 7) == hatval)
330 result = hat_dir_map[hatval];
331 else
333 return result;
334}
335
336
337static int
338BSD_JoystickOpen(SDL_Joystick * joy, int device_index)
339{
340 char *path = joynames[device_index];
341 struct joystick_hwdata *hw;
342 struct hid_item hitem;
343 struct hid_data *hdata;
344 struct report *rep = NULL;
345#if defined(__NetBSD__)
346 usb_device_descriptor_t udd;
347 struct usb_string_desc usd;
348#endif
349 int fd;
350 int i;
351
352 fd = open(path, O_RDONLY);
353 if (fd == -1) {
354 return SDL_SetError("%s: %s", path, strerror(errno));
355 }
356
357 joy->instance_id = device_index;
358 hw = (struct joystick_hwdata *)
359 SDL_malloc(sizeof(struct joystick_hwdata));
360 if (hw == NULL) {
361 close(fd);
362 return SDL_OutOfMemory();
363 }
364 joy->hwdata = hw;
365 hw->fd = fd;
366 hw->path = SDL_strdup(path);
367 if (!SDL_strncmp(path, "/dev/joy", 8)) {
368 hw->type = BSDJOY_JOY;
369 joy->naxes = 2;
370 joy->nbuttons = 2;
371 joy->nhats = 0;
372 joy->nballs = 0;
373 joydevnames[device_index] = SDL_strdup("Gameport joystick");
374 goto usbend;
375 } else {
376 hw->type = BSDJOY_UHID;
377 }
378
379 {
380 int ax;
381 for (ax = 0; ax < JOYAXE_count; ax++)
382 hw->axis_map[ax] = -1;
383 }
384 hw->repdesc = hid_get_report_desc(fd);
385 if (hw->repdesc == NULL) {
386 SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
387 strerror(errno));
388 goto usberr;
389 }
390 rep = &hw->inreport;
391#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
392 rep->rid = hid_get_report_id(fd);
393 if (rep->rid < 0) {
394#else
395 if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
396#endif
397 rep->rid = -1; /* XXX */
398 }
399#if defined(__NetBSD__)
400 if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1)
401 goto desc_failed;
402
403 /* Get default language */
404 usd.usd_string_index = USB_LANGUAGE_TABLE;
405 usd.usd_language_id = 0;
406 if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) {
407 usd.usd_language_id = 0;
408 } else {
409 usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
410 }
411
412 usd.usd_string_index = udd.iProduct;
413 if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
414 char str[128];
415 char *new_name = NULL;
416 int i;
417 for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) {
418 str[i] = UGETW(usd.usd_desc.bString[i]);
419 }
420 str[i] = '\0';
421 asprintf(&new_name, "%s @ %s", str, path);
422 if (new_name != NULL) {
423 SDL_free(joydevnames[numjoysticks]);
424 joydevnames[numjoysticks] = new_name;
425 }
426 }
427desc_failed:
428#endif
429 if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
430 goto usberr;
431 }
432 if (rep->size <= 0) {
433 SDL_SetError("%s: Input report descriptor has invalid length",
434 hw->path);
435 goto usberr;
436 }
437#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
438 hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
439#else
440 hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
441#endif
442 if (hdata == NULL) {
443 SDL_SetError("%s: Cannot start HID parser", hw->path);
444 goto usberr;
445 }
446 joy->naxes = 0;
447 joy->nbuttons = 0;
448 joy->nhats = 0;
449 joy->nballs = 0;
450 for (i = 0; i < JOYAXE_count; i++)
451 hw->axis_map[i] = -1;
452
453 while (hid_get_item(hdata, &hitem) > 0) {
454 char *sp;
455 const char *s;
456
457 switch (hitem.kind) {
458 case hid_collection:
459 switch (HID_PAGE(hitem.usage)) {
460 case HUP_GENERIC_DESKTOP:
461 switch (HID_USAGE(hitem.usage)) {
462 case HUG_JOYSTICK:
463 case HUG_GAME_PAD:
464 s = hid_usage_in_page(hitem.usage);
465 sp = SDL_malloc(SDL_strlen(s) + 5);
466 SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)",
467 s, device_index);
468 joydevnames[device_index] = sp;
469 }
470 }
471 break;
472 case hid_input:
473 switch (HID_PAGE(hitem.usage)) {
474 case HUP_GENERIC_DESKTOP:
475 {
476 unsigned usage = HID_USAGE(hitem.usage);
477 int joyaxe = usage_to_joyaxe(usage);
478 if (joyaxe >= 0) {
479 hw->axis_map[joyaxe] = 1;
480 } else if (usage == HUG_HAT_SWITCH
481#ifdef __OpenBSD__
482 || usage == HUG_DPAD_UP
483#endif
484 ) {
485 joy->nhats++;
486 }
487 break;
488 }
489 case HUP_BUTTON:
490 joy->nbuttons++;
491 break;
492 default:
493 break;
494 }
495 break;
496 default:
497 break;
498 }
499 }
500 hid_end_parse(hdata);
501 for (i = 0; i < JOYAXE_count; i++)
502 if (hw->axis_map[i] > 0)
503 hw->axis_map[i] = joy->naxes++;
504
505 if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) {
506 SDL_SetError("%s: Not a joystick, ignoring", hw->path);
507 goto usberr;
508 }
509
510 usbend:
511 /* The poll blocks the event thread. */
512 fcntl(fd, F_SETFL, O_NONBLOCK);
513#ifdef __NetBSD__
514 /* Flush pending events */
515 if (rep) {
516 while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size)
517 ;
518 }
519#endif
520
521 return (0);
522 usberr:
523 close(hw->fd);
524 SDL_free(hw->path);
525 SDL_free(hw);
526 return (-1);
527}
528
529static void
530BSD_JoystickUpdate(SDL_Joystick * joy)
531{
532 struct hid_item hitem;
533 struct hid_data *hdata;
534 struct report *rep;
535 int nbutton, naxe = -1;
536 Sint32 v;
537#ifdef __OpenBSD__
538 Sint32 dpad[4] = {0, 0, 0, 0};
539#endif
540
541#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
542 struct joystick gameport;
543 static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
544
545 if (joy->hwdata->type == BSDJOY_JOY) {
546 while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
547 if (abs(x - gameport.x) > 8) {
548 x = gameport.x;
549 if (x < xmin) {
550 xmin = x;
551 }
552 if (x > xmax) {
553 xmax = x;
554 }
555 if (xmin == xmax) {
556 xmin--;
557 xmax++;
558 }
559 v = (Sint32) x;
560 v -= (xmax + xmin + 1) / 2;
561 v *= 32768 / ((xmax - xmin + 1) / 2);
562 SDL_PrivateJoystickAxis(joy, 0, v);
563 }
564 if (abs(y - gameport.y) > 8) {
565 y = gameport.y;
566 if (y < ymin) {
567 ymin = y;
568 }
569 if (y > ymax) {
570 ymax = y;
571 }
572 if (ymin == ymax) {
573 ymin--;
574 ymax++;
575 }
576 v = (Sint32) y;
577 v -= (ymax + ymin + 1) / 2;
578 v *= 32768 / ((ymax - ymin + 1) / 2);
579 SDL_PrivateJoystickAxis(joy, 1, v);
580 }
581 SDL_PrivateJoystickButton(joy, 0, gameport.b1);
582 SDL_PrivateJoystickButton(joy, 1, gameport.b2);
583 }
584 return;
585 }
586#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
587
588 rep = &joy->hwdata->inreport;
589
590 while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
591#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
592 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
593#else
594 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
595#endif
596 if (hdata == NULL) {
597 /*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/
598 continue;
599 }
600
601 for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
602 switch (hitem.kind) {
603 case hid_input:
604 switch (HID_PAGE(hitem.usage)) {
605 case HUP_GENERIC_DESKTOP:
606 {
607 unsigned usage = HID_USAGE(hitem.usage);
608 int joyaxe = usage_to_joyaxe(usage);
609 if (joyaxe >= 0) {
610 naxe = joy->hwdata->axis_map[joyaxe];
611 /* scaleaxe */
612 v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
613 v -= (hitem.logical_maximum +
614 hitem.logical_minimum + 1) / 2;
615 v *= 32768 /
616 ((hitem.logical_maximum -
617 hitem.logical_minimum + 1) / 2);
618 SDL_PrivateJoystickAxis(joy, naxe, v);
619 } else if (usage == HUG_HAT_SWITCH) {
620 v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
622 hatval_to_sdl(v) -
623 hitem.logical_minimum);
624 }
625#ifdef __OpenBSD__
626 else if (usage == HUG_DPAD_UP) {
627 dpad[0] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
628 SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
629 }
630 else if (usage == HUG_DPAD_DOWN) {
631 dpad[1] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
632 SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
633 }
634 else if (usage == HUG_DPAD_RIGHT) {
635 dpad[2] = (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_LEFT) {
639 dpad[3] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
640 SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
641 }
642#endif
643 break;
644 }
645 case HUP_BUTTON:
646 v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
647 SDL_PrivateJoystickButton(joy, nbutton, v);
648 nbutton++;
649 break;
650 default:
651 continue;
652 }
653 break;
654 default:
655 break;
656 }
657 }
658 hid_end_parse(hdata);
659 }
660}
661
662/* Function to close a joystick after use */
663static void
664BSD_JoystickClose(SDL_Joystick * joy)
665{
666 if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
667 report_free(&joy->hwdata->inreport);
668 hid_dispose_report_desc(joy->hwdata->repdesc);
669 }
670 close(joy->hwdata->fd);
671 SDL_free(joy->hwdata->path);
672 SDL_free(joy->hwdata);
673}
674
675static void
676BSD_JoystickQuit(void)
677{
678 int i;
679
680 for (i = 0; i < MAX_JOYS; i++) {
681 SDL_free(joynames[i]);
682 SDL_free(joydevnames[i]);
683 }
684
685 return;
686}
687
688static SDL_JoystickGUID
689BSD_JoystickGetDeviceGUID( int device_index )
690{
691 SDL_JoystickGUID guid;
692 /* the GUID is just the first 16 chars of the name for now */
693 const char *name = BSD_JoystickGetDeviceName( device_index );
694 SDL_zero( guid );
695 SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
696 return guid;
697}
698
699static int
700report_alloc(struct report *r, struct report_desc *rd, int repind)
701{
702 int len;
703
704#ifdef __DragonFly__
705 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
706#elif __FREEBSD__
707# if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
708# if (__FreeBSD_kernel_version <= 500111)
709 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
710# else
711 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
712# endif
713# else
714 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
715# endif
716#else
717# ifdef USBHID_NEW
718 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
719# else
720 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
721# endif
722#endif
723
724 if (len < 0) {
725 return SDL_SetError("Negative HID report size");
726 }
727 r->size = len;
728
729 if (r->size > 0) {
730#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
731 r->buf = SDL_malloc(r->size);
732#else
733 r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
734 r->size);
735#endif
736 if (r->buf == NULL) {
737 return SDL_OutOfMemory();
738 }
739 } else {
740 r->buf = NULL;
741 }
742
743 r->status = SREPORT_CLEAN;
744 return 0;
745}
746
747static void
748report_free(struct report *r)
749{
750 SDL_free(r->buf);
751 r->status = SREPORT_UNINIT;
752}
753
754static int
755BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
756{
757 return SDL_Unsupported();
758}
759
761{
762 BSD_JoystickInit,
763 BSD_JoystickGetCount,
764 BSD_JoystickDetect,
765 BSD_JoystickGetDeviceName,
766 BSD_JoystickGetDevicePlayerIndex,
767 BSD_JoystickGetDeviceGUID,
768 BSD_JoystickGetDeviceInstanceID,
769 BSD_JoystickOpen,
770 BSD_JoystickRumble,
771 BSD_JoystickUpdate,
772 BSD_JoystickClose,
773 BSD_JoystickQuit,
774};
775
776#endif /* SDL_JOYSTICK_USBHID */
777
778/* 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:52
#define SDL_Unsupported()
Definition: SDL_error.h:53
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:890
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:833
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:966
#define SDL_HAT_LEFTDOWN
Definition: SDL_joystick.h:337
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:333
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:331
#define SDL_HAT_RIGHTUP
Definition: SDL_joystick.h:334
#define SDL_HAT_LEFTUP
Definition: SDL_joystick.h:336
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:332
#define SDL_HAT_RIGHTDOWN
Definition: SDL_joystick.h:335
#define SDL_HAT_UP
Definition: SDL_joystick.h:330
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:329
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
GLuint64EXT * result
GLenum GLsizei len
GLuint const GLchar * name
GLsizeiptr size
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei const GLchar *const * path
GLsizeiptr const void GLenum usage
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
uint32_t Uint32
Definition: SDL_stdinc.h:203
int32_t Sint32
Definition: SDL_stdinc.h:197
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_JoystickDriver SDL_BSD_JoystickDriver
static int numjoysticks
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:167
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
int HID_API_EXPORT HID_API_CALL hid_init(void)
Initialize the HIDAPI library.