SDL: Fixed building with libusb not dynamicaly loaded (ffcf3)

From ffcf32b4ff1727ea854c7c2b53f08f70c3cf8b39 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 12 Sep 2022 23:55:56 +0300
Subject: [PATCH] Fixed building with libusb not dynamicaly loaded

(cherry-picked from commit 3f89d1704d84f20253e0c86a8af2aebdca6f5409)
(cherry-picked from commit 4ebf34857ad4706e9c5a7577aed6682fff778138)
(cherry-picked from commit 5767dc710ef1b375ce622495d408afbc8ad8af34)
(cherry-picked from commit 9d77945d366fb29320929254cba79c279e36e167)
(cherry-picked from commit 284769633864df4b1395f164dc16d03163973a63)
---
 cmake/sdlchecks.cmake      |   2 +-
 configure                  |   2 +
 configure.ac               |   1 +
 include/SDL_config.h.cmake |   1 +
 include/SDL_config.h.in    |   1 +
 include/SDL_config_os2.h   |   1 +
 src/hidapi/SDL_hidapi.c    | 128 ++++++++++++++++++++++++-------------
 src/hidapi/SDL_hidapi_c.h  |   2 +-
 8 files changed, 93 insertions(+), 45 deletions(-)

diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
index 7e2507505e5..80f31c7d797 100644
--- a/cmake/sdlchecks.cmake
+++ b/cmake/sdlchecks.cmake
@@ -1186,7 +1186,7 @@ macro(CheckHIDAPI)
           set(HAVE_LIBUSB TRUE)
           set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUSB_CFLAGS}")
           if(HIDAPI_ONLY_LIBUSB)
-            list(APPEND EXTRA_LIBS ${LIBUSB_LIBS})
+            list(APPEND EXTRA_LIBS ${LIBUSB_LIBRARIES})
           elseif(OS2)
             set(SDL_LIBUSB_DYNAMIC "\"usb100.dll\"")
           else()
diff --git a/configure b/configure
index bb4bdefa8e2..aabeb1cdfbd 100755
--- a/configure
+++ b/configure
@@ -28016,6 +28016,8 @@ fi
 
         if test x$hidapi_support = xyes; then
             if test x$have_libusb_h = xyes; then
+                printf "%s\n" "#define HAVE_LIBUSB 1" >>confdefs.h
+
                 EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS"
                 if test x$require_hidapi_libusb = xyes; then
                     EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS"
diff --git a/configure.ac b/configure.ac
index 1295d396d7e..6b438a2fcc3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3579,6 +3579,7 @@ CheckHIDAPI()
 
         if test x$hidapi_support = xyes; then
             if test x$have_libusb_h = xyes; then
+                AC_DEFINE(HAVE_LIBUSB)
                 EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS"
                 if test x$require_hidapi_libusb = xyes; then
                     EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS"
diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake
index 2d21b37ddce..204a12e0cbf 100644
--- a/include/SDL_config.h.cmake
+++ b/include/SDL_config.h.cmake
@@ -224,6 +224,7 @@
 #cmakedefine HAVE_INOTIFY_INIT 1
 #cmakedefine HAVE_INOTIFY_INIT1 1
 #cmakedefine HAVE_INOTIFY 1
+#cmakedefine HAVE_LIBUSB 1
 #cmakedefine HAVE_O_CLOEXEC 1
 
 /* Apple platforms might be building universal binaries, where Intel builds
diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in
index 7b6eb5db7eb..56b53029a77 100644
--- a/include/SDL_config.h.in
+++ b/include/SDL_config.h.in
@@ -227,6 +227,7 @@
 #undef HAVE_IBUS_IBUS_H
 #undef HAVE_IMMINTRIN_H
 #undef HAVE_LIBUDEV_H
+#undef HAVE_LIBUSB
 #undef HAVE_LIBSAMPLERATE_H
 #undef HAVE_LIBDECOR_H
 #undef HAVE_LSXINTRIN_H
diff --git a/include/SDL_config_os2.h b/include/SDL_config_os2.h
index 1583245ee9c..c86769db4ea 100644
--- a/include/SDL_config_os2.h
+++ b/include/SDL_config_os2.h
@@ -43,6 +43,7 @@
 /*#undef SDL_JOYSTICK_HIDAPI */
 #else
 #define SDL_JOYSTICK_HIDAPI 1
+#define HAVE_LIBUSB 1
 /* dynamically loaded libusb-1.0 dll: */
 #define SDL_LIBUSB_DYNAMIC "usb100.dll"
 #endif
diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c
index 718e5c192d6..8234963802b 100644
--- a/src/hidapi/SDL_hidapi.c
+++ b/src/hidapi/SDL_hidapi.c
@@ -681,7 +681,7 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL;
 #endif /* HAVE_DRIVER_BACKEND */
 
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
 /* libusb HIDAPI Implementation */
 
 /* Include this now, for our dynamically-loaded libusb context */
@@ -816,6 +816,33 @@ SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
 #undef HIDAPI_H__
 #include "libusb/hid.c"
 
+#undef libusb_init
+#undef libusb_exit
+#undef libusb_get_device_list
+#undef libusb_free_device_list
+#undef libusb_get_device_descriptor
+#undef libusb_get_active_config_descriptor
+#undef libusb_get_config_descriptor
+#undef libusb_free_config_descriptor
+#undef libusb_get_bus_number
+#undef libusb_get_device_address
+#undef libusb_open
+#undef libusb_close
+#undef libusb_claim_interface
+#undef libusb_release_interface
+#undef libusb_kernel_driver_active
+#undef libusb_detach_kernel_driver
+#undef libusb_attach_kernel_driver
+#undef libusb_set_interface_alt_setting
+#undef libusb_alloc_transfer
+#undef libusb_submit_transfer
+#undef libusb_cancel_transfer
+#undef libusb_free_transfer
+#undef libusb_control_transfer
+#undef libusb_interrupt_transfer
+#undef libusb_handle_events
+#undef libusb_handle_events_completed
+
 #undef hid_device
 #undef hid_device_
 #undef hid_init
@@ -843,7 +870,7 @@ SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
 #undef make_path
 #undef read_thread
 
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 
 #endif /* !SDL_HIDAPI_DISABLED */
 
@@ -898,7 +925,7 @@ static const struct hidapi_backend DRIVER_Backend = {
 };
 #endif /* HAVE_DRIVER_BACKEND */
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
 static const struct hidapi_backend LIBUSB_Backend = {
     (void*)LIBUSB_hid_write,
     (void*)LIBUSB_hid_read_timeout,
@@ -913,7 +940,7 @@ static const struct hidapi_backend LIBUSB_Backend = {
     (void*)LIBUSB_hid_get_indexed_string,
     (void*)LIBUSB_hid_error
 };
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 
 struct SDL_hid_device_
 {
@@ -923,7 +950,7 @@ struct SDL_hid_device_
 };
 static char device_magic;
 
-#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
+#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
 
 static SDL_hid_device *
 CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend)
@@ -935,7 +962,7 @@ CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend)
     return wrapper;
 }
 
-#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
 
 static void
 DeleteHIDDeviceWrapper(SDL_hid_device *device)
@@ -951,7 +978,7 @@ DeleteHIDDeviceWrapper(SDL_hid_device *device)
     }
 
 #if !SDL_HIDAPI_DISABLED
-#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
+#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
 
 #define COPY_IF_EXISTS(var) \
     if (pSrc->var != NULL) { \
@@ -988,7 +1015,7 @@ CopyHIDDeviceInfo(struct SDL_hid_device_info *pSrc, struct SDL_hid_device_info *
 #undef COPY_IF_EXISTS
 #undef WCOPY_IF_EXISTS
 
-#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
 #endif /* !SDL_HIDAPI_DISABLED */
 
 static int SDL_hidapi_refcount = 0;
@@ -1033,16 +1060,21 @@ int SDL_hid_init(void)
     }
 #endif
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
     if (SDL_getenv("SDL_HIDAPI_DISABLE_LIBUSB") != NULL) {
         SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
                      "libusb disabled by SDL_HIDAPI_DISABLE_LIBUSB");
         libusb_ctx.libhandle = NULL;
     } else {
         ++attempts;
+#ifdef SDL_LIBUSB_DYNAMIC
         libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC);
+#else
+        libusb_ctx.libhandle = (void *)1;
+#endif
         if (libusb_ctx.libhandle != NULL) {
             SDL_bool loaded = SDL_TRUE;
+#ifdef SDL_LIBUSB_DYNAMIC
             #ifdef __OS2__
             #define LOAD_LIBUSB_SYMBOL(func) \
                 if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle,"_libusb_" #func))) {loaded = SDL_FALSE;}
@@ -1050,6 +1082,10 @@ int SDL_hid_init(void)
             #define LOAD_LIBUSB_SYMBOL(func) \
                 if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) {loaded = SDL_FALSE;}
             #endif
+#else
+            #define LOAD_LIBUSB_SYMBOL(func) \
+                libusb_ctx.func = libusb_##func;
+#endif
             LOAD_LIBUSB_SYMBOL(init)
             LOAD_LIBUSB_SYMBOL(exit)
             LOAD_LIBUSB_SYMBOL(get_device_list)
@@ -1079,18 +1115,22 @@ int SDL_hid_init(void)
             #undef LOAD_LIBUSB_SYMBOL
 
             if (!loaded) {
+#ifdef SDL_LIBUSB_DYNAMIC
                 SDL_UnloadObject(libusb_ctx.libhandle);
+#endif
                 libusb_ctx.libhandle = NULL;
                 /* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function"); */
             } else if (LIBUSB_hid_init() < 0) {
+#ifdef SDL_LIBUSB_DYNAMIC
                 SDL_UnloadObject(libusb_ctx.libhandle);
+#endif
                 libusb_ctx.libhandle = NULL;
             } else {
                 ++success;
             }
         }
     }
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 
 #if HAVE_PLATFORM_BACKEND
     ++attempts;
@@ -1136,13 +1176,15 @@ int SDL_hid_exit(void)
 #endif /* __LINUX __ */
 #endif /* HAVE_PLATFORM_BACKEND */
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
     if (libusb_ctx.libhandle) {
         result |= LIBUSB_hid_exit();
+#ifdef SDL_LIBUSB_DYNAMIC
         SDL_UnloadObject(libusb_ctx.libhandle);
+#endif
         libusb_ctx.libhandle = NULL;
     }
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 
     return result;
 }
@@ -1171,8 +1213,8 @@ Uint32 SDL_hid_device_change_count(void)
 
 struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id)
 {
-#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
-#ifdef SDL_LIBUSB_DYNAMIC
+#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
+#ifdef HAVE_LIBUSB
     struct SDL_hid_device_info *usb_devs = NULL;
     struct SDL_hid_device_info *usb_dev;
 #endif
@@ -1190,7 +1232,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
         return NULL;
     }
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
     if (libusb_ctx.libhandle) {
         usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
 #ifdef DEBUG_HIDAPI
@@ -1219,7 +1261,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
             last = new_dev;
         }
     }
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 
 #ifdef HAVE_DRIVER_BACKEND
     driver_devs = DRIVER_hid_enumerate(vendor_id, product_id);
@@ -1249,7 +1291,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
                     raw_dev->manufacturer_string, raw_dev->product_string,
                     raw_dev->vendor_id, raw_dev->product_id);
 #endif
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
             for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
                 if (raw_dev->vendor_id == usb_dev->vendor_id &&
                     raw_dev->product_id == usb_dev->product_id &&
@@ -1272,7 +1314,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
             if (!bFound) {
                 new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info));
                 if (!new_dev) {
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
                     if (libusb_ctx.libhandle) {
                         LIBUSB_hid_free_enumeration(usb_devs);
                     }
@@ -1297,7 +1339,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
     }
 #endif /* HAVE_PLATFORM_BACKEND */
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
     if (libusb_ctx.libhandle) {
         LIBUSB_hid_free_enumeration(usb_devs);
     }
@@ -1306,7 +1348,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
 
 #else
     return NULL;
-#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
 }
 
 void SDL_hid_free_enumeration(struct SDL_hid_device_info *devs)
@@ -1324,7 +1366,7 @@ void SDL_hid_free_enumeration(struct SDL_hid_device_info *devs)
 
 SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
 {
-#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
+#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
     void *pDevice = NULL;
 
     if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) {
@@ -1344,21 +1386,21 @@ SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id
     }
 #endif /* HAVE_DRIVER_BACKEND */
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
     if (libusb_ctx.libhandle &&
         (pDevice = LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) {
         return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
     }
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 
-#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
 
     return NULL;
 }
 
 SDL_hid_device *SDL_hid_open_path(const char *path, int bExclusive /* = false */)
 {
-#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
+#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
     void *pDevice = NULL;
 
     if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) {
@@ -1378,14 +1420,14 @@ SDL_hid_device *SDL_hid_open_path(const char *path, int bExclusive /* = false */
     }
 #endif /* HAVE_DRIVER_BACKEND */
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
     if (libusb_ctx.libhandle &&
         (pDevice = LIBUSB_hid_open_path(path, bExclusive)) != NULL) {
         return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
     }
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 
-#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
 
     return NULL;
 }
@@ -1539,7 +1581,7 @@ void SDL_hid_ble_scan(SDL_bool active)
 /* This is needed to enable input for Nyko and EVORETRO GameCube adaptors */
 void SDL_EnableGameCubeAdaptors(void)
 {
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
     libusb_context *context = NULL;
     libusb_device **devs = NULL;
     libusb_device_handle *handle = NULL;
@@ -1551,10 +1593,10 @@ void SDL_EnableGameCubeAdaptors(void)
         return;
     }
 
-    if (libusb_init(&context) == 0) {
-        num_devs = libusb_get_device_list(context, &devs);
+    if (libusb_ctx.init(&context) == 0) {
+        num_devs = libusb_ctx.get_device_list(context, &devs);
         for (i = 0; i < num_devs; ++i) {
-            if (libusb_get_device_descriptor(devs[i], &desc) != 0) {
+            if (libusb_ctx.get_device_descriptor(devs[i], &desc) != 0) {
                 continue;
             }
 
@@ -1562,33 +1604,33 @@ void SDL_EnableGameCubeAdaptors(void)
                 continue;
             }
 
-            if (libusb_open(devs[i], &handle) != 0) {
+            if (libusb_ctx.open(devs[i], &handle) != 0) {
                 continue;
             }
 
-            if (libusb_kernel_driver_active(handle, 0)) {
-                if (libusb_detach_kernel_driver(handle, 0) == 0) {
+            if (libusb_ctx.kernel_driver_active(handle, 0)) {
+                if (libusb_ctx.detach_kernel_driver(handle, 0) == 0) {
                     kernel_detached = 1;
                 }
             }
 
-            if (libusb_claim_interface(handle, 0) == 0) {
-                libusb_control_transfer(handle, 0x21, 11, 0x0001, 0, NULL, 0, 1000);
-                libusb_release_interface(handle, 0);
+            if (libusb_ctx.claim_interface(handle, 0) == 0) {
+                libusb_ctx.control_transfer(handle, 0x21, 11, 0x0001, 0, NULL, 0, 1000);
+                libusb_ctx.release_interface(handle, 0);
             }
 
             if (kernel_detached) {
-                libusb_attach_kernel_driver(handle, 0);
+                libusb_ctx.attach_kernel_driver(handle, 0);
             }
 
-            libusb_close(handle);
+            libusb_ctx.close(handle);
         }
 
-        libusb_free_device_list(devs, 1);
+        libusb_ctx.free_device_list(devs, 1);
 
-        libusb_exit(context);
+        libusb_ctx.exit(context);
     }
-#endif /* SDL_LIBUSB_DYNAMIC */
+#endif /* HAVE_LIBUSB */
 }
 #endif /* HAVE_ENABLE_GAMECUBE_ADAPTORS */
 
diff --git a/src/hidapi/SDL_hidapi_c.h b/src/hidapi/SDL_hidapi_c.h
index 1b409423278..c7343b126b0 100644
--- a/src/hidapi/SDL_hidapi_c.h
+++ b/src/hidapi/SDL_hidapi_c.h
@@ -22,7 +22,7 @@
 
 #ifdef SDL_JOYSTICK_HIDAPI
 
-#ifdef SDL_LIBUSB_DYNAMIC
+#ifdef HAVE_LIBUSB
 #define HAVE_ENABLE_GAMECUBE_ADAPTORS
 #endif