Skip to content

Commit

Permalink
hidapi: Add SDL_hidapi.c, allows support for multiple hidapi backends.
Browse files Browse the repository at this point in the history
This is currently supported on Linux and macOS. iOS and Android are not
supported at all, Windows support could be added with some changes to the libusb
backend. The Visual Studio and Xcode projects do not use this feature.

Based on Valve Software's hid.cpp, written in collaboration with Andrew Eikum.
  • Loading branch information
flibitijibibo committed Jul 31, 2019
1 parent c10a874 commit f7d82e5
Show file tree
Hide file tree
Showing 7 changed files with 847 additions and 27 deletions.
20 changes: 13 additions & 7 deletions CMakeLists.txt
Expand Up @@ -156,11 +156,10 @@ if(UNIX OR MINGW OR MSYS)
endif()

# The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers,
# so we'll just use libusb when it's available. Except that libusb
# requires root permissions to open devices, so that's not generally
# useful, and we'll disable this by default on Unix. Windows and macOS
# can use it without root access, though, so enable by default there.
if(WINDOWS OR APPLE OR ANDROID)
# so we'll just use libusb when it's available. libusb does not support iOS,
# so we default to yes on iOS.
# TODO: Windows can support libusb, the hid.c file just depends on Unix APIs
if(WINDOWS OR IOS OR ANDROID)
set(HIDAPI_SKIP_LIBUSB TRUE)
else()
set(HIDAPI_SKIP_LIBUSB FALSE)
Expand All @@ -169,6 +168,14 @@ if (HIDAPI_SKIP_LIBUSB)
set(OPT_DEF_HIDAPI ON)
endif()

# On the other hand, *BSD specifically uses libusb only, so we make a special
# case just for them.
if(FREEBSD OR NETBSD OR OPENBSD OR BSDI)
set(HIDAPI_ONLY_LIBUSB TRUE)
else()
set(HIDAPI_ONLY_LIBUSB FALSE)
endif()

# Compiler info
if(CMAKE_COMPILER_IS_GNUCC)
set(USE_GCC TRUE)
Expand Down Expand Up @@ -1376,6 +1383,7 @@ elseif(WINDOWS)

if(SDL_JOYSTICK)
CheckHIDAPI()
# TODO: Remove this hid.c block when SDL_hidapi.c is supported on Windows!
if(HAVE_HIDAPI)
set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/windows/hid.c)
endif()
Expand Down Expand Up @@ -1466,8 +1474,6 @@ elseif(APPLE)
if(HAVE_HIDAPI)
if(IOS)
set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/ios/hid.m)
else()
set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/mac/hid.c)
endif()
endif()
set(SDL_JOYSTICK_IOKIT 1)
Expand Down
11 changes: 9 additions & 2 deletions cmake/sdlchecks.cmake
Expand Up @@ -1088,8 +1088,15 @@ macro(CheckHIDAPI)
set(SOURCE_FILES ${SOURCE_FILES} ${HIDAPI_SOURCES})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUSB_CFLAGS} -I${SDL2_SOURCE_DIR}/src/hidapi/hidapi")
if(NOT HIDAPI_SKIP_LIBUSB)
set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/libusb/hid.c)
list(APPEND EXTRA_LIBS ${LIBUSB_LIBS})
if(HIDAPI_ONLY_LIBUSB)
set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/libusb/hid.c)
list(APPEND EXTRA_LIBS ${LIBUSB_LIBS})
else()
set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/SDL_hidapi.c)
# libusb is loaded dynamically, so don't add it to EXTRA_LIBS
FindLibraryAndSONAME("usb-1.0")
set(SDL_LIBUSB_DYNAMIC "\"${USB_LIB_SONAME}\"")
endif()
endif()
endif()
endif()
Expand Down
50 changes: 41 additions & 9 deletions configure
Expand Up @@ -24106,16 +24106,24 @@ CheckHIDAPI()
# The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers,
# so we'll just use libusb when it's available.
#
# Except that libusb requires root permissions to open devices, so that's not generally useful, and we'll disable this by default.
#
# On macOS and Windows, where you don't need libusb or root, we default to yes.
# libusb does not support iOS, so we default to yes on iOS.
# TODO: Windows can support libusb, the hid.c file just depends on Unix APIs
skiplibusb=no
case "$host" in
*-*-cygwin* | *-*-mingw32* | *-*-darwin* )
*-*-cygwin* | *-*-mingw32* | arm*-apple-darwin* | *-ios-* )
skiplibusb=yes
;;
esac

# On the other hand, *BSD specifically uses libusb only, so we make a
# special case just for them.
onlylibusb=no
case "$host" in
*-*-*bsd* )
onlylibusb=yes
;;
esac

# Check whether --enable-hidapi was given.
if test "${enable_hidapi+set}" = set; then :
enableval=$enable_hidapi;
Expand Down Expand Up @@ -24224,9 +24232,35 @@ $as_echo "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"

if test x$skiplibusb = xno; then
SOURCES="$SOURCES $srcdir/src/hidapi/libusb/hid.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS"
if test x$onlylibusb = xyes; then
SOURCES="$SOURCES $srcdir/src/hidapi/libusb/hid.c"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS"
else
if test x$have_loadso != xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libusb loading" >&5
$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libusb loading" >&2;}
fi
SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c"
# libusb is loaded dynamically, so don't add it to LDFLAGS
libusb_lib=""
case "$host" in
*-*-darwin* )
libusb_lib="libusb-1.0.0.dylib"
;;
*-*-cygwin* | *-*-mingw32* )
libusb_lib="libusb-1.0.dll"
;;
esac
if test x$libusb_lib = x; then
libusb_lib=`find_lib "libusb-1.0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`
fi

cat >>confdefs.h <<_ACEOF
#define SDL_LIBUSB_DYNAMIC "$libusb_lib"
_ACEOF

fi
fi
fi

Expand Down Expand Up @@ -24732,6 +24766,7 @@ $as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h
fi
SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
have_joystick=yes
# TODO: Remove this block once SDL_hidapi.c supports Windows!
if test x$hidapi_support = xyes; then
SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
fi
Expand Down Expand Up @@ -25077,9 +25112,6 @@ $as_echo "#define SDL_JOYSTICK_IOKIT 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/joystick/darwin/*.c"
have_joystick=yes
if test x$hidapi_support = xyes; then
SOURCES="$SOURCES $srcdir/src/hidapi/mac/hid.c"
fi
fi
# Set up files for the haptic library
if test x$enable_haptic = xyes; then
Expand Down
45 changes: 36 additions & 9 deletions configure.ac
Expand Up @@ -3198,16 +3198,24 @@ CheckHIDAPI()
# The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers,
# so we'll just use libusb when it's available.
#
# Except that libusb requires root permissions to open devices, so that's not generally useful, and we'll disable this by default.
#
# On macOS and Windows, where you don't need libusb or root, we default to yes.
# libusb does not support iOS, so we default to yes on iOS.
# TODO: Windows can support libusb, the hid.c file just depends on Unix APIs
skiplibusb=no
case "$host" in
*-*-cygwin* | *-*-mingw32* | *-*-darwin* )
*-*-cygwin* | *-*-mingw32* | arm*-apple-darwin* | *-ios-* )
skiplibusb=yes
;;
esac

# On the other hand, *BSD specifically uses libusb only, so we make a
# special case just for them.
onlylibusb=no
case "$host" in
*-*-*bsd* )
onlylibusb=yes
;;
esac

AC_ARG_ENABLE(hidapi,
AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[default=maybe]]]),
, enable_hidapi=maybe)
Expand Down Expand Up @@ -3237,9 +3245,30 @@ AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[d
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"

if test x$skiplibusb = xno; then
SOURCES="$SOURCES $srcdir/src/hidapi/libusb/hid.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS"
if test x$onlylibusb = xyes; then
SOURCES="$SOURCES $srcdir/src/hidapi/libusb/hid.c"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS"
else
if test x$have_loadso != xyes; then
AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic libusb loading])
fi
SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c"
# libusb is loaded dynamically, so don't add it to LDFLAGS
libusb_lib=""
case "$host" in
*-*-darwin* )
libusb_lib="libusb-1.0.0.dylib"
;;
*-*-cygwin* | *-*-mingw32* )
libusb_lib="libusb-1.0.dll"
;;
esac
if test x$libusb_lib = x; then
libusb_lib=[`find_lib "libusb-1.0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`]
fi
AC_DEFINE_UNQUOTED(SDL_LIBUSB_DYNAMIC, "$libusb_lib", [ ])
fi
fi
fi

Expand Down Expand Up @@ -3599,6 +3628,7 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
fi
SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
have_joystick=yes
# TODO: Remove this block once SDL_hidapi.c supports Windows!
if test x$hidapi_support = xyes; then
SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
fi
Expand Down Expand Up @@ -3842,9 +3872,6 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
AC_DEFINE(SDL_JOYSTICK_IOKIT, 1, [ ])
SOURCES="$SOURCES $srcdir/src/joystick/darwin/*.c"
have_joystick=yes
if test x$hidapi_support = xyes; then
SOURCES="$SOURCES $srcdir/src/hidapi/mac/hid.c"
fi
fi
# Set up files for the haptic library
if test x$enable_haptic = xyes; then
Expand Down
1 change: 1 addition & 0 deletions include/SDL_config.h.cmake
Expand Up @@ -294,6 +294,7 @@
#cmakedefine SDL_HAPTIC_DINPUT @SDL_HAPTIC_DINPUT@
#cmakedefine SDL_HAPTIC_XINPUT @SDL_HAPTIC_XINPUT@
#cmakedefine SDL_HAPTIC_ANDROID @SDL_HAPTIC_ANDROID@
#cmakedefine SDL_LIBUSB_DYNAMIC @SDL_LIBUSB_DYNAMIC@

/* Enable various sensor drivers */
#cmakedefine SDL_SENSOR_ANDROID @SDL_SENSOR_ANDROID@
Expand Down
3 changes: 3 additions & 0 deletions include/SDL_config.h.in
Expand Up @@ -412,6 +412,9 @@
/* Enable dynamic udev support */
#undef SDL_UDEV_DYNAMIC

/* Enable dynamic libusb support */
#undef SDL_LIBUSB_DYNAMIC

/* Enable dynamic libsamplerate support */
#undef SDL_LIBSAMPLERATE_DYNAMIC

Expand Down

0 comments on commit f7d82e5

Please sign in to comment.