23 #ifdef SDL_JOYSTICK_USBHID
32 #include <sys/param.h>
38 #ifndef __FreeBSD_kernel_version
39 #define __FreeBSD_kernel_version __FreeBSD_version
42 #if defined(HAVE_USB_H)
46 #include <bus/usb/usb.h>
47 #include <bus/usb/usbhid.h>
49 #include <dev/usb/usb.h>
50 #include <dev/usb/usbhid.h>
53 #if defined(HAVE_USBHID_H)
55 #elif defined(HAVE_LIBUSB_H)
57 #elif defined(HAVE_LIBUSBHID_H)
58 #include <libusbhid.h>
61 #if defined(__FREEBSD__) || defined(__FreeBSD_kernel__)
63 #include <osreldate.h>
65 #if __FreeBSD_kernel_version > 800063
66 #include <dev/usb/usb_ioctl.h>
68 #include <sys/joystick.h>
71 #if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
72 #include <machine/joystick.h>
76 #include "../SDL_sysjoystick.h"
77 #include "../SDL_joystick_c.h"
79 #define MAX_UHID_JOYS 16
80 #define MAX_JOY_JOYS 2
81 #define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS)
86 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
88 #elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
89 struct usb_gen_descriptor *
buf;
91 struct usb_ctl_report *
buf;
108 }
const repinfo[] = {
109 {UHID_INPUT_REPORT, hid_input,
"input"},
110 {UHID_OUTPUT_REPORT, hid_output,
"output"},
111 {UHID_FEATURE_REPORT, hid_feature,
"feature"}
143 struct report_desc *repdesc;
144 struct report inreport;
145 int axis_map[JOYAXE_count];
148 static char *joynames[MAX_JOYS];
149 static char *joydevnames[MAX_JOYS];
151 static int report_alloc(
struct report *,
struct report_desc *,
int);
152 static void report_free(
struct report *);
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)
161 #define REP_BUF_DATA(rep) ((rep)->buf->data)
164 static int SDL_SYS_numjoysticks = 0;
172 SDL_SYS_numjoysticks = 0;
175 SDL_memset(joydevnames, 0,
sizeof(joydevnames));
177 for (i = 0; i < MAX_UHID_JOYS; i++) {
182 joynames[SDL_SYS_numjoysticks] =
strdup(s);
186 SDL_SYS_numjoysticks++;
188 SDL_free(joynames[SDL_SYS_numjoysticks]);
189 joynames[SDL_SYS_numjoysticks] =
NULL;
192 for (i = 0; i < MAX_JOY_JOYS; i++) {
194 fd = open(s, O_RDONLY);
196 joynames[SDL_SYS_numjoysticks++] =
strdup(s);
204 return (SDL_SYS_numjoysticks);
209 return SDL_SYS_numjoysticks;
224 if (joydevnames[device_index] !=
NULL) {
225 return (joydevnames[device_index]);
227 return (joynames[device_index]);
237 usage_to_joyaxe(
unsigned usage)
251 joyaxe = JOYAXE_SLIDER;
254 joyaxe = JOYAXE_WHEEL;
272 hatval_to_sdl(
Sint32 hatval)
274 static const unsigned hat_dir_map[8] = {
279 if ((hatval & 7) == hatval)
280 result = hat_dir_map[hatval];
290 char *
path = joynames[device_index];
292 struct hid_item hitem;
293 struct hid_data *hdata;
298 fd = open(path, O_RDONLY);
314 hw->type = BSDJOY_JOY;
319 joydevnames[device_index] =
strdup(
"Gameport joystick");
322 hw->type = BSDJOY_UHID;
327 for (ax = 0; ax < JOYAXE_count; ax++)
328 hw->axis_map[ax] = -1;
330 hw->repdesc = hid_get_report_desc(fd);
331 if (hw->repdesc ==
NULL) {
337 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
338 rep->rid = hid_get_report_id(fd);
341 if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
345 if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
348 if (rep->size <= 0) {
349 SDL_SetError(
"%s: Input report descriptor has invalid length",
353 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
354 hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
356 hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
366 for (i = 0; i < JOYAXE_count; i++)
367 hw->axis_map[i] = -1;
369 while (hid_get_item(hdata, &hitem) > 0) {
373 switch (hitem.kind) {
375 switch (HID_PAGE(hitem.usage)) {
376 case HUP_GENERIC_DESKTOP:
377 switch (HID_USAGE(hitem.usage)) {
380 s = hid_usage_in_page(hitem.usage);
384 joydevnames[device_index] = sp;
389 switch (HID_PAGE(hitem.usage)) {
390 case HUP_GENERIC_DESKTOP:
392 unsigned usage = HID_USAGE(hitem.usage);
393 int joyaxe = usage_to_joyaxe(usage);
395 hw->axis_map[joyaxe] = 1;
396 }
else if (usage == HUG_HAT_SWITCH) {
412 hid_end_parse(hdata);
413 for (i = 0; i < JOYAXE_count; i++)
414 if (hw->axis_map[i] > 0)
415 hw->axis_map[
i] = joy->
naxes++;
419 fcntl(fd, F_SETFL, O_NONBLOCK);
438 struct hid_item hitem;
439 struct hid_data *hdata;
441 int nbutton, naxe = -1;
444 #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
445 struct joystick gameport;
446 static int x,
y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
448 if (joy->
hwdata->type == BSDJOY_JOY) {
449 while (read(joy->
hwdata->
fd, &gameport,
sizeof gameport) ==
sizeof gameport) {
450 if (abs(x - gameport.x) > 8) {
463 v -= (xmax + xmin + 1) / 2;
464 v *= 32768 / ((xmax - xmin + 1) / 2);
467 if (abs(y - gameport.y) > 8) {
480 v -= (ymax + ymin + 1) / 2;
481 v *= 32768 / ((ymax - ymin + 1) / 2);
484 if (gameport.b1 != joy->
buttons[0]) {
487 if (gameport.b2 != joy->
buttons[1]) {
495 rep = &joy->
hwdata->inreport;
497 while (read(joy->
hwdata->
fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
498 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
499 hdata = hid_start_parse(joy->
hwdata->repdesc, 1 << hid_input, rep->rid);
501 hdata = hid_start_parse(joy->
hwdata->repdesc, 1 << hid_input);
508 for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
509 switch (hitem.kind) {
511 switch (HID_PAGE(hitem.usage)) {
512 case HUP_GENERIC_DESKTOP:
514 unsigned usage = HID_USAGE(hitem.usage);
515 int joyaxe = usage_to_joyaxe(usage);
517 naxe = joy->
hwdata->axis_map[joyaxe];
519 v = (
Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
520 v -= (hitem.logical_maximum +
521 hitem.logical_minimum + 1) / 2;
523 ((hitem.logical_maximum -
524 hitem.logical_minimum + 1) / 2);
525 if (v != joy->
axes[naxe]) {
528 }
else if (usage == HUG_HAT_SWITCH) {
529 v = (
Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
532 hitem.logical_minimum);
537 v = (
Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
538 if (joy->
buttons[nbutton] != v) {
551 hid_end_parse(hdata);
560 report_free(&joy->
hwdata->inreport);
561 hid_dispose_report_desc(joy->
hwdata->repdesc);
575 for (i = 0; i < MAX_JOYS; i++) {
597 const char *name = joystick->
name;
604 report_alloc(
struct report *
r,
struct report_desc *rd,
int repind)
609 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
611 # if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
612 # if (__FreeBSD_kernel_version <= 500111)
613 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
615 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
618 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
622 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
624 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
634 #if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
637 r->buf =
SDL_malloc(
sizeof(*r->buf) -
sizeof(REP_BUF_DATA(r)) +
640 if (r->buf ==
NULL) {
647 r->status = SREPORT_CLEAN;
652 report_free(
struct report *r)
655 r->status = SREPORT_UNINIT;
int32_t Sint32
A signed 32-bit integer type.
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
char * strdup(const char *inStr)
int SDL_SYS_NumJoysticks()
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
DECLSPEC void SDLCALL SDL_free(void *mem)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
EGLImageKHR EGLint * name
void SDL_SYS_JoystickQuit(void)
GLsizei const GLchar *const * path
struct joystick_hwdata * hwdata
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
#define SDL_HAT_RIGHTDOWN
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
void SDL_SYS_JoystickDetect()
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen)
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
SDL_bool SDL_SYS_JoystickNeedsPolling()
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
int SDL_SYS_JoystickInit(void)
EGLSurface EGLint EGLint y
#define SDL_OutOfMemory()
#define SDL_arraysize(array)
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
GLenum GLuint GLsizei const GLchar * buf
GLdouble GLdouble GLdouble r
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
GLsizeiptr const GLvoid GLenum usage
SDL_JoystickID instance_id
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)