SDL: Separated the HIDAPI subsystem from HIDAPI joysticks

From a0f8afb599025fb336b0fcf5176577961080eac3 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 11 Nov 2021 09:16:44 -0800
Subject: [PATCH] Separated the HIDAPI subsystem from HIDAPI joysticks

You can now disable HIDAPI joysticks while retaining the HIDAPI SDL API
---
 CMakeLists.txt        | 37 ++++++++++++++--------------
 cmake/sdlchecks.cmake | 56 ++++++++++++++++++++++++++-----------------
 configure             | 49 +++++++++++++++++++++++--------------
 configure.ac          | 28 +++++++++++++---------
 4 files changed, 100 insertions(+), 70 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d26126d043..5f40063c9b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,9 +186,6 @@ if((WINDOWS AND NOT WINDOWS_STORE) OR IOS OR TVOS OR ANDROID)
 else()
   set(HIDAPI_SKIP_LIBUSB FALSE)
 endif()
-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.
@@ -424,9 +421,9 @@ set_option(SDL_METAL               "Enable Metal support" ${APPLE})
 set_option(SDL_KMSDRM              "Use KMS DRM video driver" ${UNIX_SYS})
 dep_option(SDL_KMSDRM_SHARED       "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF)
 set_option(SDL_OFFSCREEN           "Use offscreen video driver" OFF)
-option_string(SDL_BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" "OFF")
-option_string(SDL_FOREGROUNDING_SIGNAL "number to use for magic foregrounding signal or 'OFF'" "OFF")
-set_option(SDL_HIDAPI              "Use HIDAPI for low level joystick drivers" ${OPT_DEF_HIDAPI})
+option_string(SDL_BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" OFF)
+option_string(SDL_FOREGROUNDING_SIGNAL "number to use for magic foregrounding signal or 'OFF'" OFF)
+set_option(SDL_HIDAPI_JOYSTICK     "Use HIDAPI for low level joystick drivers" ON)
 set_option(SDL_VIRTUAL_JOYSTICK    "Enable the virtual-joystick driver" ON)
 set_option(SDL_ASAN                "Use AddressSanitizer to detect memory errors" OFF)
 
@@ -1053,11 +1050,10 @@ if(ANDROID)
     set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_HAPTIC_SOURCES})
     set(HAVE_SDL_HAPTIC TRUE)
   endif()
-  if(SDL_JOYSTICK)
+  if(SDL_HIDAPI)
     CheckHIDAPI()
-    if(HAVE_HIDAPI)
-      set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/android/hid.cpp)
-    endif()
+  endif()
+  if(SDL_JOYSTICK)
     set(SDL_JOYSTICK_ANDROID 1)
     file(GLOB ANDROID_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/android/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
     set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_JOYSTICK_SOURCES})
@@ -1380,11 +1376,14 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS AND NOT HAIKU)
     # src/core/unix/*.c is included in a generic if(UNIX) section, elsewhere.
   endif()
 
+  if(SDL_HIDAPI)
+    CheckHIDAPI()
+  endif()
+
   if(SDL_JOYSTICK)
     if(FREEBSD OR NETBSD OR OPENBSD OR BSDI)
       CheckUSBHID()
     endif()
-    CheckHIDAPI()
     if(LINUX AND NOT ANDROID)
       set(SDL_JOYSTICK_LINUX 1)
       file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
@@ -1706,8 +1705,11 @@ elseif(WINDOWS)
     endif()
   endif()
 
-  if(SDL_JOYSTICK)
+  if(SDL_HIDAPI)
     CheckHIDAPI()
+  endif()
+
+  if(SDL_JOYSTICK)
     if(NOT WINDOWS_STORE)
       set(SDL_JOYSTICK_RAWINPUT 1)
     endif()
@@ -1802,14 +1804,11 @@ elseif(APPLE)
     set(SDL_FRAMEWORK_AVFOUNDATION 1)
   endif()
 
-  if(SDL_JOYSTICK)
+  if(SDL_HIDAPI)
     CheckHIDAPI()
-    if(HAVE_HIDAPI)
-      if(IOS OR TVOS)
-        set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/ios/hid.m)
-        set(SDL_FRAMEWORK_COREBLUETOOTH 1)
-      endif()
-    endif()
+  endif()
+
+  if(SDL_JOYSTICK)
     if(IOS OR TVOS)
       file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
       set(SDL_JOYSTICK_MFI 1)
diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
index 8d8bed9925..23b8793d27 100644
--- a/cmake/sdlchecks.cmake
+++ b/cmake/sdlchecks.cmake
@@ -1129,29 +1129,17 @@ macro(CheckUSBHID)
   endif()
 endmacro()
 
-# Check for HIDAPI joystick drivers. This is currently a Unix thing, not Windows or macOS!
+# Check for HIDAPI support
 macro(CheckHIDAPI)
-  if(SDL_HIDAPI)
-    if(HIDAPI_SKIP_LIBUSB)
-      set(HAVE_HIDAPI TRUE)
-    else()
-      set(HAVE_HIDAPI FALSE)
-      pkg_check_modules(LIBUSB libusb-1.0)
-      if (LIBUSB_FOUND)
-        check_include_file(libusb.h HAVE_LIBUSB_H ${LIBUSB_CFLAGS})
-        if (HAVE_LIBUSB_H)
-          set(HAVE_HIDAPI TRUE)
-        endif()
-      endif()
-    endif()
-
-    if(HAVE_HIDAPI)
-      set(SDL_JOYSTICK_HIDAPI 1)
-      set(HAVE_SDL_JOYSTICK TRUE)
-      file(GLOB HIDAPI_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/hidapi/*.c)
-      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(HAVE_HIDAPI TRUE)
+  if(NOT HIDAPI_SKIP_LIBUSB)
+    set(HAVE_LIBUSB FALSE)
+    pkg_check_modules(LIBUSB libusb-1.0)
+    if (LIBUSB_FOUND)
+      check_include_file(libusb.h HAVE_LIBUSB_H ${LIBUSB_CFLAGS})
+      if(HAVE_LIBUSB_H)
+        set(HAVE_LIBUSB TRUE)
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUSB_CFLAGS}")
         if(HIDAPI_ONLY_LIBUSB)
           list(APPEND EXTRA_LIBS ${LIBUSB_LIBS})
         else()
@@ -1161,6 +1149,30 @@ macro(CheckHIDAPI)
         endif()
       endif()
     endif()
+    if(HIDAPI_ONLY_LIBUSB AND NOT HAVE_LIBUSB)
+      set(HAVE_HIDAPI FALSE)
+    endif()
+  endif()
+
+  if(HAVE_HIDAPI)
+    if(ANDROID)
+      set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/android/hid.cpp)
+    endif()
+    if(IOS OR TVOS)
+      set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/ios/hid.m)
+      set(SDL_FRAMEWORK_COREBLUETOOTH 1)
+    endif()
+    set(HAVE_SDL_HIDAPI TRUE)
+
+    if(SDL_JOYSTICK AND SDL_HIDAPI_JOYSTICK)
+      set(SDL_JOYSTICK_HIDAPI 1)
+      set(HAVE_SDL_JOYSTICK TRUE)
+      set(HAVE_HIDAPI_JOYSTICK TRUE)
+      file(GLOB HIDAPI_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/hidapi/*.c)
+      set(SOURCE_FILES ${SOURCE_FILES} ${HIDAPI_JOYSTICK_SOURCES})
+    endif()
+  else()
+    set(SDL_HIDAPI_DISABLED 1)
   endif()
 endmacro()
 
diff --git a/configure b/configure
index c9b1952d15..023f26bd2c 100755
--- a/configure
+++ b/configure
@@ -813,6 +813,7 @@ enable_render
 enable_events
 enable_joystick
 enable_haptic
+enable_hidapi
 enable_sensor
 enable_power
 enable_filesystem
@@ -903,7 +904,7 @@ enable_pthread_sem
 enable_directx
 enable_xinput
 enable_wasapi
-enable_hidapi
+enable_hidapi_joystick
 enable_hidapi_libusb
 enable_clock_gettime
 enable_rpath
@@ -1587,6 +1588,7 @@ Optional Features:
   --enable-joystick       Enable the joystick subsystem [default=yes]
   --enable-haptic         Enable the haptic (force feedback) subsystem
                           [default=yes]
+  --enable-hidapi         Enable the HIDAPI subsystem [default=yes]
   --enable-sensor         Enable the sensor subsystem [default=yes]
   --enable-power          Enable the power subsystem [default=yes]
   --enable-filesystem     Enable the filesystem subsystem [default=yes]
@@ -1698,7 +1700,8 @@ Optional Features:
   --enable-directx        use DirectX for Windows audio/video [default=yes]
   --enable-xinput         use Xinput for Windows [default=yes]
   --enable-wasapi         use the Windows WASAPI audio driver [default=yes]
-  --enable-hidapi         use HIDAPI for low level joystick drivers
+  --enable-hidapi-joystick
+                          use HIDAPI for low level joystick drivers
                           [default=yes]
   --enable-hidapi-libusb  use libusb for low level joystick drivers
                           [default=maybe]
@@ -17430,6 +17433,20 @@ $as_echo "#define SDL_HAPTIC_DISABLED 1" >>confdefs.h
 else
     SUMMARY_modules="${SUMMARY_modules} haptic"
 fi
+# Check whether --enable-hidapi was given.
+if test "${enable_hidapi+set}" = set; then :
+  enableval=$enable_hidapi;
+else
+  enable_hidapi=yes
+fi
+
+if test x$enable_hidapi != xyes; then
+
+$as_echo "#define SDL_HIDAPI_DISABLED 1" >>confdefs.h
+
+else
+    SUMMARY_modules="${SUMMARY_modules} hidapi"
+fi
 # Check whether --enable-sensor was given.
 if test "${enable_sensor+set}" = set; then :
   enableval=$enable_sensor;
@@ -24618,11 +24635,11 @@ $as_echo "#define SDL_JOYSTICK_USBHID 1" >>confdefs.h
 
 CheckHIDAPI()
 {
-    # Check whether --enable-hidapi was given.
-if test "${enable_hidapi+set}" = set; then :
-  enableval=$enable_hidapi;
+    # Check whether --enable-hidapi-joystick was given.
+if test "${enable_hidapi_joystick+set}" = set; then :
+  enableval=$enable_hidapi_joystick;
 else
-  enable_hidapi=yes
+  enable_hidapi_joystick=yes
 fi
 
     # Check whether --enable-hidapi-libusb was given.
@@ -24633,13 +24650,7 @@ else
 fi
 
 
-    if test x$enable_hidapi != xyes; then
-
-$as_echo "#define SDL_HIDAPI_DISABLED 1" >>confdefs.h
-
-    fi
-
-    if test x$enable_joystick = xyes -a x$enable_hidapi = xyes; then
+    if test x$enable_hidapi = xyes; then
         case "$host" in
             # libusb does not support iOS
             *-ios-* )
@@ -24742,11 +24753,6 @@ fi
         fi
 
         if test x$hidapi_support = xyes; then
-
-$as_echo "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h
-
-            SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
-
             if test x$have_libusb_h = xyes; then
                 EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS"
                 if test x$require_hidapi_libusb = xyes; then
@@ -24787,6 +24793,13 @@ $as_echo_n "checking for hidapi support... " >&6; }
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hidapi_support" >&5
 $as_echo "$hidapi_support" >&6; }
     fi
+
+    if test x$enable_joystick = xyes -a x$hidapi_support = xyes -a x$enable_hidapi_joystick = xyes; then
+
+$as_echo "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h
+
+        SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
+    fi
 }
 
 CheckClockGettime()
diff --git a/configure.ac b/configure.ac
index aeb2ccd391..322f166f96 100644
--- a/configure.ac
+++ b/configure.ac
@@ -482,6 +482,14 @@ if test x$enable_haptic != xyes; then
 else
     SUMMARY_modules="${SUMMARY_modules} haptic"
 fi
+AC_ARG_ENABLE(hidapi,
+[AS_HELP_STRING([--enable-hidapi], [Enable the HIDAPI subsystem [default=yes]])],
+              , enable_hidapi=yes)
+if test x$enable_hidapi != xyes; then
+    AC_DEFINE(SDL_HIDAPI_DISABLED, 1, [ ])
+else
+    SUMMARY_modules="${SUMMARY_modules} hidapi"
+fi
 AC_ARG_ENABLE(sensor,
 [AS_HELP_STRING([--enable-sensor], [Enable the sensor subsystem [default=yes]])],
               , enable_sensor=yes)
@@ -3411,18 +3419,14 @@ CheckUSBHID()
 dnl Check for HIDAPI joystick drivers
 CheckHIDAPI()
 {
-    AC_ARG_ENABLE(hidapi,
-[AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [default=yes]])],
-                  , enable_hidapi=yes)
+    AC_ARG_ENABLE(hidapi-joystick,
+[AS_HELP_STRING([--enable-hidapi-joystick], [use HIDAPI for low level joystick drivers [default=yes]])],
+                  , enable_hidapi_joystick=yes)
     AC_ARG_ENABLE(hidapi-libusb,
 [AS_HELP_STRING([--enable-hidapi-libusb], [use libusb for low level joystick drivers [default=maybe]])],
                   , enable_hidapi_libusb=maybe)
 
-    if test x$enable_hidapi != xyes; then
-        AC_DEFINE(SDL_HIDAPI_DISABLED, 1, [ ])
-    fi
-
-    if test x$enable_joystick = xyes -a x$enable_hidapi = xyes; then
+    if test x$enable_hidapi = xyes; then
         case "$host" in
             # libusb does not support iOS
             *-ios-* )
@@ -3448,9 +3452,6 @@ CheckHIDAPI()
         fi
 
         if test x$hidapi_support = xyes; then
-            AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ])
-            SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
-
             if test x$have_libusb_h = xyes; then
                 EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS"
                 if test x$require_hidapi_libusb = xyes; then
@@ -3482,6 +3483,11 @@ CheckHIDAPI()
         AC_MSG_CHECKING(for hidapi support)
         AC_MSG_RESULT($hidapi_support)
     fi
+
+    if test x$enable_joystick = xyes -a x$hidapi_support = xyes -a x$enable_hidapi_joystick = xyes; then
+        AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ])
+        SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
+    fi
 }
 
 dnl Check for clock_gettime()