SDL_net: Make compatible with Windows + build everything with Cmake

From b168ca00c6cf66e31ca8bfa356a69bccdc3bc3d1 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Mon, 14 Aug 2023 02:52:02 +0200
Subject: [PATCH] Make compatible with Windows + build everything with Cmake

---
 CMakeLists.txt | 20 +++++++++++++++++++-
 SDL_net.c      | 26 ++++++++++++++++++++++----
 2 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 012731d..1407b40 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,22 @@
 cmake_minimum_required(VERSION 3.16)
-project(SDL3_net)
+project(SDL3_net VERSION 3.0.0)
+
+find_package(SDL3 REQUIRED COMPONENTS SDL3)
+
 add_library(SDL3_net SHARED SDL_net.c)
+add_library(SDL3_net::SDL3_net ALIAS SDL3_net)
+target_include_directories(SDL3_net PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
+target_link_libraries(SDL3_net PRIVATE SDL3::SDL3)
+if(WIN32)
+    target_link_libraries(SDL3_net PRIVATE ws2_32)
+endif()
+if(UNIX AND NOT APPLE)
+    set_property(TARGET SDL3_net PROPERTY SOVERSION ${PROJECT_VERSION_MAJOR})
+    set_property(TARGET SDL3_net PROPERTY VERSION ${PROJECT_VERSION})
+endif()
+if(NOT MSVC)
+    target_link_options(SDL3_net PRIVATE -Wl,--no-undefined)
+endif()
 
+add_executable(voipchat examples/voipchat.c)
+target_link_libraries(voipchat PRIVATE SDL3_net::SDL3_net SDL3::SDL3)
diff --git a/SDL_net.c b/SDL_net.c
index 5278dad..488073f 100644
--- a/SDL_net.c
+++ b/SDL_net.c
@@ -3,10 +3,28 @@
 #ifdef __WINDOWS__
 #define WIN32_LEAN_AND_MEAN 1
 #include <windows.h>
-#include <winsock.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
 typedef SOCKET Socket;
 typedef int SockLen;
 typedef SOCKADDR_STORAGE AddressStorage;
+static int write(SOCKET s, const char *buf, size_t count) {
+    return send(s, buf, count, 0);
+}
+static int read(SOCKET s, char *buf, size_t count) {
+    WSABUF wsabuf;
+    wsabuf.buf = buf;
+    wsabuf.len = count;
+    DWORD count_received;
+    int res = WSARecv(s, &wsabuf, 1, &count_received, 0, NULL, NULL);
+    if (res != 0) {
+        SDL_SetError("WSARecv(%d)", WSAGetLastError());
+        return -1;
+    }
+    return (int)count_received;
+}
+#define EAI_SYSTEM 0
+#define poll WSAPoll
 #else
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -585,7 +603,7 @@ static int CheckClientConnection(SDLNet_StreamSocket *sock, int timeoutms)
             } else if ((pfd.revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) {
                 int err = 0;
                 SockLen errsize = sizeof (err);
-                getsockopt(sock->handle, SOL_SOCKET, SO_ERROR, &err, &errsize);
+                getsockopt(sock->handle, SOL_SOCKET, SO_ERROR, (char*)&err, &errsize);
                 sock->status = SDL_SetError("Socket failed to connect: %s", strerror(err));
             } else if (pfd.revents & POLLOUT) {
                 sock->status = 1;  // good to go!
@@ -692,7 +710,7 @@ int SDLNet_WaitForServerIncoming(SDLNet_Server *server)
     } else if ((pfd.revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) {
         int err = 0;
         SockLen errsize = sizeof (err);
-        getsockopt(server->handle, SOL_SOCKET, SO_ERROR, &err, &errsize);
+        getsockopt(server->handle, SOL_SOCKET, SO_ERROR, (char*)&err, &errsize);
         return SDL_SetError("Listen socket has failed: %s", strerror(err));
     } else if (pfd.revents & POLLIN) {
         return 0;
@@ -915,7 +933,7 @@ int SDLNet_WaitForStreamPendingWrites(SDLNet_StreamSocket *sock)
         } else if ((pfd.revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) {
             int err = 0;
             SockLen errsize = sizeof (err);
-            getsockopt(sock->handle, SOL_SOCKET, SO_ERROR, &err, &errsize);
+            getsockopt(sock->handle, SOL_SOCKET, SO_ERROR, (char*)&err, &errsize);
             return SDL_SetError("Socket has failed: %s", strerror(err));
         } else if (pfd.revents & POLLOUT) {
             if (PumpStreamSocket(sock) < 0) {