SDL: hidapi, libusb: don't use iconv on OS/2, it lacks wchar_t functionality.

From e9511f7136893dc22bbdf06ff8fd9f6e31325bf2 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Fri, 14 Jan 2022 14:39:04 +0300
Subject: [PATCH] hidapi, libusb: don't use iconv on OS/2, it lacks wchar_t
 functionality.

Taken from a patch by Silvan Scherrer at bitwiseworks' OS/2 fork.
---
 src/hidapi/libusb/hid.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c
index 296af5b4ee8..5cc60bcbdca 100644
--- a/src/hidapi/libusb/hid.c
+++ b/src/hidapi/libusb/hid.c
@@ -388,12 +388,16 @@ static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
 /* This function returns a newly allocated wide string containing the USB
    device string numbered by the index. The returned string must be freed
    by using free(). */
+#if defined(__OS2__) /* don't use iconv on OS/2: no support for wchar_t. */
+#define NO_ICONV
+#endif
 static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
 {
 	char buf[512];
 	int len;
 	wchar_t *str = NULL;
 
+#if !defined(NO_ICONV)
 	wchar_t wbuf[256];
 	SDL_iconv_t ic;
 	size_t inbytes;
@@ -401,6 +405,9 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
 	size_t res;
 	const char *inptr;
 	char *outptr;
+#else
+	int i;
+#endif
 
 	/* Determine which language to use. */
 	uint16_t lang;
@@ -417,6 +424,23 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
 	if (len < 0)
 		return NULL;
 
+#if defined(NO_ICONV) /* original hidapi code for NO_ICONV : */
+
+	/* Bionic does not have wchar_t iconv support, so it
+	   has to be done manually.  The following code will only work for
+	   code points that can be represented as a single UTF-16 character,
+	   and will incorrectly convert any code points which require more
+	   than one UTF-16 character.
+
+	   Skip over the first character (2-bytes).  */
+	len -= 2;
+	str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t));
+	for (i = 0; i < len / 2; i++) {
+		str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
+	}
+	str[len / 2] = 0x00000000;
+
+#else
 	/* buf does not need to be explicitly NULL-terminated because
 	   it is only passed into iconv() which does not need it. */
 
@@ -449,6 +473,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
 
 err:
 	SDL_iconv_close(ic);
+#endif
 
 	return str;
 }