Pārlūkot izejas kodu

Update SDL to 2.28.5.

Miku AuahDark 2 gadi atpakaļ
vecāks
revīzija
3b80a5a766
52 mainītis faili ar 656 papildinājumiem un 182 dzēšanām
  1. 51 0
      love/src/jni/SDL2/.github/workflows/cpactions.yml
  2. 1 1
      love/src/jni/SDL2/.github/workflows/emscripten.yml
  3. 1 1
      love/src/jni/SDL2/.github/workflows/main.yml
  4. 1 1
      love/src/jni/SDL2/.github/workflows/msvc.yml
  5. 40 4
      love/src/jni/SDL2/CMakeLists.txt
  6. 1 1
      love/src/jni/SDL2/Makefile.os2
  7. 1 1
      love/src/jni/SDL2/Makefile.w32
  8. 2 2
      love/src/jni/SDL2/Xcode/SDL/Info-Framework.plist
  9. 6 6
      love/src/jni/SDL2/Xcode/SDL/SDL.xcodeproj/project.pbxproj
  10. 1 1
      love/src/jni/SDL2/Xcode/SDL/pkg-support/SDL.info
  11. 1 0
      love/src/jni/SDL2/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
  12. 1 1
      love/src/jni/SDL2/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
  13. 6 2
      love/src/jni/SDL2/build-scripts/config.guess
  14. 110 45
      love/src/jni/SDL2/build-scripts/config.sub
  15. 18 0
      love/src/jni/SDL2/cmake/sdlchecks.cmake
  16. 2 0
      love/src/jni/SDL2/cmake/sdlplatform.cmake
  17. 1 1
      love/src/jni/SDL2/configure
  18. 1 1
      love/src/jni/SDL2/configure.ac
  19. 1 1
      love/src/jni/SDL2/docs/README-emscripten.md
  20. 2 0
      love/src/jni/SDL2/include/SDL_config.h.cmake
  21. 3 4
      love/src/jni/SDL2/include/SDL_config_android.h
  22. 1 1
      love/src/jni/SDL2/include/SDL_version.h
  23. 10 2
      love/src/jni/SDL2/src/SDL_assert.c
  24. 2 2
      love/src/jni/SDL2/src/audio/arts/SDL_artsaudio.c
  25. 2 0
      love/src/jni/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c
  26. 2 0
      love/src/jni/SDL2/src/audio/qsa/SDL_qsa_audio.c
  27. 2 2
      love/src/jni/SDL2/src/core/android/SDL_android.c
  28. 1 0
      love/src/jni/SDL2/src/hidapi/libusb/hid.c
  29. 18 0
      love/src/jni/SDL2/src/joystick/SDL_joystick.c
  30. 1 0
      love/src/jni/SDL2/src/joystick/controller_list.h
  31. 48 20
      love/src/jni/SDL2/src/joystick/hidapi/SDL_hidapi_ps5.c
  32. 7 0
      love/src/jni/SDL2/src/joystick/hidapi/SDL_hidapijoystick.c
  33. 1 1
      love/src/jni/SDL2/src/joystick/linux/SDL_sysjoystick.c
  34. 4 4
      love/src/jni/SDL2/src/main/windows/version.rc
  35. 3 5
      love/src/jni/SDL2/src/misc/emscripten/SDL_sysurl.c
  36. 13 0
      love/src/jni/SDL2/src/misc/unix/SDL_sysurl.c
  37. 1 1
      love/src/jni/SDL2/src/render/SDL_render.c
  38. 13 8
      love/src/jni/SDL2/src/render/software/SDL_triangle.c
  39. 6 10
      love/src/jni/SDL2/src/stdlib/SDL_iconv.c
  40. 71 0
      love/src/jni/SDL2/src/stdlib/SDL_string.c
  41. 24 2
      love/src/jni/SDL2/src/test/SDL_test_compare.c
  42. 3 1
      love/src/jni/SDL2/src/test/SDL_test_fuzzer.c
  43. 13 8
      love/src/jni/SDL2/src/video/SDL_blit_slow.c
  44. 1 0
      love/src/jni/SDL2/src/video/android/SDL_androidevents.c
  45. 12 1
      love/src/jni/SDL2/src/video/emscripten/SDL_emscriptenmouse.c
  46. 8 2
      love/src/jni/SDL2/src/video/wayland/SDL_waylandevents.c
  47. 10 16
      love/src/jni/SDL2/src/video/wayland/SDL_waylandwindow.c
  48. 1 4
      love/src/jni/SDL2/src/video/x11/SDL_x11clipboard.c
  49. 11 18
      love/src/jni/SDL2/src/video/x11/SDL_x11mouse.c
  50. 7 0
      love/src/jni/SDL2/test/CMakeLists.txt
  51. 77 1
      love/src/jni/SDL2/test/testautomation_stdlib.c
  52. 32 0
      love/src/jni/SDL2/test/testfilesystem_pre.c

+ 51 - 0
love/src/jni/SDL2/.github/workflows/cpactions.yml

@@ -0,0 +1,51 @@
+name: Build (C/P Actions)
+
+on: [push, pull_request]
+
+jobs:
+  freebsd:
+    runs-on: ubuntu-latest
+    name: FreeBSD
+    timeout-minutes: 30
+    steps:
+    - uses: actions/checkout@v3
+    - name: Build
+      uses: cross-platform-actions/[email protected]
+      with:
+        operating_system: freebsd
+        version: '13.2'
+        shell: bash
+        run: |
+          sudo pkg update
+          sudo pkg install -y \
+              gmake \
+              pkgconf \
+              libXcursor \
+              libXext \
+              libXinerama \
+              libXi \
+              libXfixes \
+              libXrandr \
+              libXScrnSaver \
+              libXxf86vm \
+              wayland \
+              wayland-protocols \
+              libxkbcommon \
+              mesa-libs \
+              libglvnd \
+              evdev-proto \
+              libinotify \
+              alsa-lib \
+              jackit \
+              pipewire \
+              pulseaudio \
+              sndio \
+              dbus \
+              zh-fcitx \
+              ibus \
+              libudev-devd
+          mkdir build_autotools
+          export CPPFLAGS="-I/usr/local/include"
+          export LDFLAGS="-L/usr/local/lib"
+          (cd build_autotools && ../configure --disable-static)
+          gmake -C build_autotools -j`sysctl -n hw.ncpu` V=1

+ 1 - 1
love/src/jni/SDL2/.github/workflows/emscripten.yml

@@ -9,7 +9,7 @@ jobs:
       - uses: actions/checkout@v3
       - uses: mymindstorm/setup-emsdk@v12
         with:
-          version: 2.0.32
+          version: 3.1.35
       - name: Install ninja
         run: |
           sudo apt-get -y update

+ 1 - 1
love/src/jni/SDL2/.github/workflows/main.yml

@@ -107,7 +107,7 @@ jobs:
         ${{ matrix.platform.source_cmd }}
         set -eu
         export SDL_TESTS_QUICK=1
-        ctest -VV --test-dir build/
+        ctest -VV --test-dir build/ -j2
         if test "${{ runner.os }}" = "Linux"; then
           # This should show us the SDL_REVISION
           strings build/libSDL2-2.0.so.0 | grep SDL-

+ 1 - 1
love/src/jni/SDL2/.github/workflows/msvc.yml

@@ -53,7 +53,7 @@ jobs:
       if: "! contains(matrix.platform.name, 'ARM')"
       run: |
         $env:SDL_TESTS_QUICK=1
-        ctest -VV --test-dir build/ -C Release
+        ctest -VV --test-dir build/ -C Release -j2
     - name: Install (CMake)
       run: |
         echo "SDL2_DIR=$Env:GITHUB_WORKSPACE/prefix" >> $Env:GITHUB_ENV

+ 40 - 4
love/src/jni/SDL2/CMakeLists.txt

@@ -2,6 +2,9 @@ if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
   message(FATAL_ERROR "Prevented in-tree build. Please create a build directory outside of the SDL source code and run \"cmake -S ${CMAKE_SOURCE_DIR} -B .\" from there")
 endif()
 
+# MSVC runtime library flags are selected by an abstraction.
+set(CMAKE_POLICY_DEFAULT_CMP0091 NEW)
+
 cmake_minimum_required(VERSION 3.0.0...3.5)
 project(SDL2 C CXX)
 
@@ -84,7 +87,7 @@ endif()
 # See docs/release_checklist.md
 set(SDL_MAJOR_VERSION 2)
 set(SDL_MINOR_VERSION 28)
-set(SDL_MICRO_VERSION 3)
+set(SDL_MICRO_VERSION 5)
 set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
 
 # Set defaults preventing destination file conflicts
@@ -224,11 +227,13 @@ elseif(MSVC_VERSION GREATER 1400) # VisualStudio 8.0+
 elseif(CMAKE_C_COMPILER_ID MATCHES "^Intel$")
   set(OPT_DEF_ASM TRUE)
   set(USE_INTELCC TRUE)
+elseif(CMAKE_C_COMPILER_ID MATCHES "QCC")
+  set(USE_QCC TRUE)
 else()
   set(OPT_DEF_ASM FALSE)
 endif()
 
-if(USE_GCC OR USE_CLANG OR USE_INTELCC)
+if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
   set(OPT_DEF_GCC_ATOMICS ON)
 endif()
 
@@ -253,6 +258,9 @@ endif()
 if(MSVC)
   option(SDL_FORCE_STATIC_VCRT "Force /MT for static VC runtimes" OFF)
   if(SDL_FORCE_STATIC_VCRT)
+    if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
+      set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+    endif()
     foreach(flag_var
         CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
         CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
@@ -563,7 +571,7 @@ if(NOT SDL_FOREGROUNDING_SIGNAL STREQUAL "OFF")
 endif()
 
 # Compiler option evaluation
-if(USE_GCC OR USE_CLANG OR USE_INTELCC)
+if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
   # Check for -Wall first, so later things can override pieces of it.
   # Note: clang-cl treats -Wall as -Weverything (which is very loud),
   #       /W3 as -Wall, and /W4 as -Wall -Wextra.  So: /W3 is enough.
@@ -1422,6 +1430,12 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
         file(GLOB AIX_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/paudio/*.c)
         list(APPEND SOURCE_FILES ${AIX_AUDIO_SOURCES})
         set(HAVE_SDL_AUDIO TRUE)
+    elseif(QNX)
+        set(SDL_AUDIO_DRIVER_QSA 1)
+        file(GLOB QSA_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/qsa/*.c)
+        list(APPEND SOURCE_FILES ${QSA_AUDIO_SOURCES})
+        list(APPEND EXTRA_LIBS asound)
+        set(HAVE_SDL_AUDIO TRUE)
     endif()
     CheckOSS()
     CheckALSA()
@@ -1453,6 +1467,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
       set(SDL_VIDEO_VULKAN 1)
       set(HAVE_VULKAN TRUE)
     endif()
+    CheckQNXScreen()
   endif()
 
   if(UNIX)
@@ -1703,6 +1718,13 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
     set(HAVE_RPATH TRUE)
   endif()
 
+  if(QNX)
+    # QNX's *printf() family generates a SIGSEGV if NULL is passed for a string
+    # specifier (on purpose), but SDL expects "(null)". Use the built-in
+    # implementation.
+    set(HAVE_VSNPRINTF 0)
+    set(USE_POSIX_SPAWN 1)
+  endif()
 elseif(WINDOWS)
   find_program(WINDRES windres)
 
@@ -3061,9 +3083,17 @@ else()
   set(sdl_static_libname "SDL2")
 endif()
 
-set(prefix ${CMAKE_INSTALL_PREFIX})
+# CMAKE_PREFIX_PATH and CMAKE_INSTALL_FULL_BINDIR can be a non-absolute path
+# when a master-project does e.g. `set(CMAKE_INSTALL_PREFIX "libs/SDL2" CACHE PATH "prefix" FORCE)`.
+if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
+  set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}")
+endif()
+if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_FULL_BINDIR}")
+  set(CMAKE_INSTALL_FULL_BINDIR "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_FULL_BINDIR}")
+endif()
 file(RELATIVE_PATH bin_prefix_relpath "${CMAKE_INSTALL_FULL_BINDIR}" "${CMAKE_INSTALL_PREFIX}")
 
+set(prefix ${CMAKE_INSTALL_PREFIX})
 set(exec_prefix "\${prefix}")
 set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
 set(bindir "\${exec_prefix}/${CMAKE_INSTALL_BINDIR}")
@@ -3307,6 +3337,12 @@ if(ANDROID)
 endif()
 
 if(APPLE)
+  cmake_push_check_state(RESET)
+  check_c_compiler_flag(-fobjc-arc COMPILER_SUPPORTS_FOBJC_ARC)
+  cmake_pop_check_state()
+  if(NOT COMPILER_SUPPORTS_FOBJC_ARC)
+    message(FATAL_ERROR "Compiler does not support -fobjc-arc: this is required on Apple platforms")
+  endif()
   target_compile_options(sdl-build-options INTERFACE "-fobjc-arc")
 endif()
 

+ 1 - 1
love/src/jni/SDL2/Makefile.os2

@@ -15,7 +15,7 @@
 LIBNAME = SDL2
 MAJOR_VERSION = 2
 MINOR_VERSION = 28
-MICRO_VERSION = 3
+MICRO_VERSION = 5
 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
 DESCRIPTION = Simple DirectMedia Layer 2
 

+ 1 - 1
love/src/jni/SDL2/Makefile.w32

@@ -6,7 +6,7 @@
 LIBNAME = SDL2
 MAJOR_VERSION = 2
 MINOR_VERSION = 28
-MICRO_VERSION = 3
+MICRO_VERSION = 5
 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
 
 LIBHOME = .

+ 2 - 2
love/src/jni/SDL2/Xcode/SDL/Info-Framework.plist

@@ -19,10 +19,10 @@
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.28.3</string>
+	<string>2.28.5</string>
 	<key>CFBundleSignature</key>
 	<string>SDLX</string>
 	<key>CFBundleVersion</key>
-	<string>2.28.3</string>
+	<string>2.28.5</string>
 </dict>
 </plist>

+ 6 - 6
love/src/jni/SDL2/Xcode/SDL/SDL.xcodeproj/project.pbxproj

@@ -9529,7 +9529,7 @@
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEPLOYMENT_POSTPROCESSING = YES;
 				DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
-				DYLIB_CURRENT_VERSION = 2801.3.0;
+				DYLIB_CURRENT_VERSION = 2801.5.0;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_ALTIVEC_EXTENSIONS = YES;
@@ -9570,7 +9570,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_LINK_OBJC_RUNTIME = NO;
-				MARKETING_VERSION = 2.28.3;
+				MARKETING_VERSION = 2.28.5;
 				OTHER_LDFLAGS = "-liconv";
 			};
 			name = Release;
@@ -9614,7 +9614,7 @@
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
-				DYLIB_CURRENT_VERSION = 2801.3.0;
+				DYLIB_CURRENT_VERSION = 2801.5.0;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
@@ -9656,7 +9656,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_LINK_OBJC_RUNTIME = NO;
-				MARKETING_VERSION = 2.28.3;
+				MARKETING_VERSION = 2.28.5;
 				OTHER_LDFLAGS = "-liconv";
 			};
 			name = Debug;
@@ -9863,7 +9863,7 @@
 				DEFINES_MODULE = YES;
 				DEVELOPMENT_TEAM = "";
 				DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
-				DYLIB_CURRENT_VERSION = 2801.3.0;
+				DYLIB_CURRENT_VERSION = 2801.5.0;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				GCC_DYNAMIC_NO_PIC = NO;
@@ -9915,7 +9915,7 @@
 				DEFINES_MODULE = YES;
 				DEVELOPMENT_TEAM = "";
 				DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
-				DYLIB_CURRENT_VERSION = 2801.3.0;
+				DYLIB_CURRENT_VERSION = 2801.5.0;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				ENABLE_NS_ASSERTIONS = NO;
 				GCC_C_LANGUAGE_STANDARD = gnu11;

+ 1 - 1
love/src/jni/SDL2/Xcode/SDL/pkg-support/SDL.info

@@ -1,4 +1,4 @@
-Title SDL 2.28.3
+Title SDL 2.28.5
 Version 1
 Description SDL Library for Mac OS X (http://www.libsdl.org)
 DefaultLocation /Library/Frameworks

+ 1 - 0
love/src/jni/SDL2/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java

@@ -273,6 +273,7 @@ public class HIDDeviceManager {
         final int XB1_IFACE_SUBCLASS = 71;
         final int XB1_IFACE_PROTOCOL = 208;
         final int[] SUPPORTED_VENDORS = {
+            0x03f0, // HP
             0x044f, // Thrustmaster
             0x045e, // Microsoft
             0x0738, // Mad Catz

+ 1 - 1
love/src/jni/SDL2/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java

@@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     private static final String TAG = "SDL";
     private static final int SDL_MAJOR_VERSION = 2;
     private static final int SDL_MINOR_VERSION = 28;
-    private static final int SDL_MICRO_VERSION = 3;
+    private static final int SDL_MICRO_VERSION = 5;
 /*
     // Display InputType.SOURCE/CLASS of events and devices
     //

+ 6 - 2
love/src/jni/SDL2/build-scripts/config.guess

@@ -4,7 +4,7 @@
 
 # shellcheck disable=SC2006,SC2268 # see below for rationale
 
-timestamp='2023-07-20'
+timestamp='2023-08-22'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -155,6 +155,9 @@ Linux|GNU|GNU/*)
 
 	set_cc_for_build
 	cat <<-EOF > "$dummy.c"
+	#if defined(__ANDROID__)
+	LIBC=android
+	#else
 	#include <features.h>
 	#if defined(__UCLIBC__)
 	LIBC=uclibc
@@ -169,6 +172,7 @@ Linux|GNU|GNU/*)
 	LIBC=musl
 	#endif
 	#endif
+	#endif
 	EOF
 	cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
 	eval "$cc_set_libc"
@@ -904,7 +908,7 @@ EOF
 	fi
 	;;
     *:FreeBSD:*:*)
-	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	UNAME_PROCESSOR=`uname -p`
 	case $UNAME_PROCESSOR in
 	    amd64)
 		UNAME_PROCESSOR=x86_64 ;;

+ 110 - 45
love/src/jni/SDL2/build-scripts/config.sub

@@ -4,7 +4,7 @@
 
 # shellcheck disable=SC2006,SC2268 # see below for rationale
 
-timestamp='2023-07-31'
+timestamp='2023-09-19'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -1181,7 +1181,7 @@ case $cpu-$vendor in
 		case $cpu in
 			1750a | 580 \
 			| a29k \
-			| aarch64 | aarch64_be \
+			| aarch64 | aarch64_be | aarch64c | arm64ec \
 			| abacus \
 			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
 			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
@@ -1200,6 +1200,7 @@ case $cpu-$vendor in
 			| d10v | d30v | dlx | dsp16xx \
 			| e2k | elxsi | epiphany \
 			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+			| javascript \
 			| h8300 | h8500 \
 			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 			| hexagon \
@@ -1284,11 +1285,12 @@ esac
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if test x$basic_os != x
+if test x"$basic_os" != x
 then
 
 # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
 # set os.
+obj=
 case $basic_os in
 	gnu/linux*)
 		kernel=linux
@@ -1488,10 +1490,16 @@ case $os in
 			os=eabi
 			;;
 		    *)
-			os=elf
+			os=
+			obj=elf
 			;;
 		esac
 		;;
+	aout* | coff* | elf* | pe*)
+		# These are machine code file formats, not OSes
+		obj=$os
+		os=
+		;;
 	*)
 		# No normalization, but not necessarily accepted, that comes below.
 		;;
@@ -1510,12 +1518,15 @@ else
 # system, and we'll never get to this point.
 
 kernel=
+obj=
 case $cpu-$vendor in
 	score-*)
-		os=elf
+		os=
+		obj=elf
 		;;
 	spu-*)
-		os=elf
+		os=
+		obj=elf
 		;;
 	*-acorn)
 		os=riscix1.2
@@ -1525,28 +1536,35 @@ case $cpu-$vendor in
 		os=gnu
 		;;
 	arm*-semi)
-		os=aout
+		os=
+		obj=aout
 		;;
 	c4x-* | tic4x-*)
-		os=coff
+		os=
+		obj=coff
 		;;
 	c8051-*)
-		os=elf
+		os=
+		obj=elf
 		;;
 	clipper-intergraph)
 		os=clix
 		;;
 	hexagon-*)
-		os=elf
+		os=
+		obj=elf
 		;;
 	tic54x-*)
-		os=coff
+		os=
+		obj=coff
 		;;
 	tic55x-*)
-		os=coff
+		os=
+		obj=coff
 		;;
 	tic6x-*)
-		os=coff
+		os=
+		obj=coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
@@ -1568,19 +1586,24 @@ case $cpu-$vendor in
 		os=sunos3
 		;;
 	m68*-cisco)
-		os=aout
+		os=
+		obj=aout
 		;;
 	mep-*)
-		os=elf
+		os=
+		obj=elf
 		;;
 	mips*-cisco)
-		os=elf
+		os=
+		obj=elf
 		;;
 	mips*-*)
-		os=elf
+		os=
+		obj=elf
 		;;
 	or32-*)
-		os=coff
+		os=
+		obj=coff
 		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
 		os=sysv3
@@ -1589,7 +1612,8 @@ case $cpu-$vendor in
 		os=sunos4.1.1
 		;;
 	pru-*)
-		os=elf
+		os=
+		obj=elf
 		;;
 	*-be)
 		os=beos
@@ -1670,10 +1694,12 @@ case $cpu-$vendor in
 		os=uxpv
 		;;
 	*-rom68k)
-		os=coff
+		os=
+		obj=coff
 		;;
 	*-*bug)
-		os=coff
+		os=
+		obj=coff
 		;;
 	*-apple)
 		os=macos
@@ -1691,7 +1717,8 @@ esac
 
 fi
 
-# Now, validate our (potentially fixed-up) OS.
+# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
+
 case $os in
 	# Sometimes we do "kernel-libc", so those need to count as OSes.
 	musl* | newlib* | relibc* | uclibc*)
@@ -1702,6 +1729,9 @@ case $os in
 	# VxWorks passes extra cpu info in the 4th filed.
 	simlinux | simwindows | spe)
 		;;
+	# See `case $cpu-$os` validation below
+	ghcjs)
+		;;
 	# Now accept the basic system types.
 	# The portable systems comes first.
 	# Each alternative MUST end in a * to match a version number.
@@ -1719,11 +1749,11 @@ case $os in
 	     | mirbsd* | netbsd* | dicos* | openedition* | ose* \
 	     | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
 	     | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
-	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
-	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+	     | bosx* | nextstep* | cxux* | oabi* \
+	     | ptx* | ecoff* | winnt* | domain* | vsta* \
 	     | udi* | lites* | ieee* | go32* | aux* | hcos* \
 	     | chorusrdb* | cegcc* | glidix* | serenity* \
-	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+	     | cygwin* | msys* | moss* | proelf* | rtems* \
 	     | midipix* | mingw32* | mingw64* | mint* \
 	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
 	     | interix* | uwin* | mks* | rhapsody* | darwin* \
@@ -1747,60 +1777,95 @@ case $os in
 	kernel* | msvc* )
 		# Restricted further below
 		;;
+	'')
+		if test x"$obj" = x
+		then
+			echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
+		fi
+		;;
 	*)
 		echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
 		exit 1
 		;;
 esac
 
+case $obj in
+	aout* | coff* | elf* | pe*)
+		;;
+	'')
+		# empty is fine
+		;;
+	*)
+		echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
+		exit 1
+		;;
+esac
+
+# Here we handle the constraint that a (synthetic) cpu and os are
+# valid only in combination with each other and nowhere else.
+case $cpu-$os in
+	# The "javascript-unknown-ghcjs" triple is used by GHC; we
+	# accept it here in order to tolerate that, but reject any
+	# variations.
+	javascript-ghcjs)
+		;;
+	javascript-* | *-ghcjs)
+		echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
+		exit 1
+		;;
+esac
+
 # As a final step for OS-related things, validate the OS-kernel combination
 # (given a valid OS), if there is a kernel.
-case $kernel-$os in
-	linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
-		   | linux-musl* | linux-relibc* | linux-uclibc* | linux-mlibc* )
+case $kernel-$os-$obj in
+	linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \
+		   | linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- )
 		;;
-	uclinux-uclibc* )
+	uclinux-uclibc*- )
 		;;
-	managarm-mlibc* | managarm-kernel* )
+	managarm-mlibc*- | managarm-kernel*- )
 		;;
-	windows*-gnu* | windows*-msvc*)
+	windows*-msvc*-)
 		;;
-	-dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* | -mlibc* )
+	-dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- )
 		# These are just libc implementations, not actual OSes, and thus
 		# require a kernel.
 		echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
 		exit 1
 		;;
-	-kernel* )
+	-kernel*- )
 		echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
 		exit 1
 		;;
-	*-kernel* )
+	*-kernel*- )
 		echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
 		exit 1
 		;;
-	*-msvc* )
+	*-msvc*- )
 		echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
 		exit 1
 		;;
-	kfreebsd*-gnu* | kopensolaris*-gnu*)
+	kfreebsd*-gnu*- | kopensolaris*-gnu*-)
 		;;
-	vxworks-simlinux | vxworks-simwindows | vxworks-spe)
+	vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
 		;;
-	nto-qnx*)
+	nto-qnx*-)
 		;;
-	os2-emx)
+	os2-emx-)
 		;;
-	*-eabi* | *-gnueabi*)
+	*-eabi*- | *-gnueabi*-)
 		;;
-	none-coff* | none-elf*)
+	none--*)
 		# None (no kernel, i.e. freestanding / bare metal),
-		# can be paired with an output format "OS"
+		# can be paired with an machine code file format
 		;;
-	-*)
+	-*-)
 		# Blank kernel with real OS is always fine.
 		;;
-	*-*)
+	--*)
+		# Blank kernel and OS with real machine code file format is always fine.
+		;;
+	*-*-*)
 		echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
 		exit 1
 		;;
@@ -1884,7 +1949,7 @@ case $vendor in
 		;;
 esac
 
-echo "$cpu-$vendor-${kernel:+$kernel-}$os"
+echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
 exit
 
 # Local variables:

+ 18 - 0
love/src/jni/SDL2/cmake/sdlchecks.cmake

@@ -905,6 +905,22 @@ macro(CheckOpenGLES)
   endif()
 endmacro()
 
+# Requires:
+# - EGL
+macro(CheckQNXScreen)
+  if(QNX AND HAVE_OPENGL_EGL)
+    check_c_source_compiles("
+        #include <screen/screen.h>
+        int main (int argc, char** argv) { return 0; }" HAVE_QNX_SCREEN)
+    if(HAVE_QNX_SCREEN)
+      set(SDL_VIDEO_DRIVER_QNX 1)
+      file(GLOB QNX_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/qnx/*.c)
+      list(APPEND SOURCE_FILES ${QNX_VIDEO_SOURCES})
+      list(APPEND EXTRA_LIBS screen EGL)
+    endif()
+  endif()
+endmacro()
+
 # Requires:
 # - nada
 # Optional:
@@ -955,6 +971,8 @@ macro(CheckPTHREAD)
     elseif(EMSCRIPTEN)
       set(PTHREAD_CFLAGS "-D_REENTRANT -pthread")
       set(PTHREAD_LDFLAGS "-pthread")
+    elseif(QNX)
+      # pthread support is baked in
     else()
       set(PTHREAD_CFLAGS "-D_REENTRANT")
       set(PTHREAD_LDFLAGS "-lpthread")

+ 2 - 0
love/src/jni/SDL2/cmake/sdlplatform.cmake

@@ -28,6 +28,8 @@ macro(SDL_DetectCMakePlatform)
       set(SDL_CMAKE_PLATFORM AIX)
     elseif(CMAKE_SYSTEM_NAME MATCHES "Minix.*")
       set(SDL_CMAKE_PLATFORM MINIX)
+    elseif(CMAKE_SYSTEM_NAME MATCHES "QNX")
+      set(SDL_CMAKE_PLATFORM QNX)
     endif()
   elseif(APPLE)
     if(CMAKE_SYSTEM_NAME MATCHES ".*Darwin.*")

+ 1 - 1
love/src/jni/SDL2/configure

@@ -3507,7 +3507,7 @@ orig_CFLAGS="$CFLAGS"
 # See docs/release_checklist.md
 SDL_MAJOR_VERSION=2
 SDL_MINOR_VERSION=28
-SDL_MICRO_VERSION=3
+SDL_MICRO_VERSION=5
 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
 
 SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`

+ 1 - 1
love/src/jni/SDL2/configure.ac

@@ -13,7 +13,7 @@ dnl Set various version strings - taken gratefully from the GTk sources
 # See docs/release_checklist.md
 SDL_MAJOR_VERSION=2
 SDL_MINOR_VERSION=28
-SDL_MICRO_VERSION=3
+SDL_MICRO_VERSION=5
 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
 
 SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`

+ 1 - 1
love/src/jni/SDL2/docs/README-emscripten.md

@@ -38,7 +38,7 @@ for some Javascript code to steal for this approach.
 
 ## Building SDL/emscripten
 
-SDL currently requires at least Emscripten 2.0.32 to build. Newer versions
+SDL currently requires at least Emscripten 3.1.35 to build. Newer versions
 are likely to work, as well.
 
 

+ 2 - 0
love/src/jni/SDL2/include/SDL_config.h.cmake

@@ -262,6 +262,8 @@
 #cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@
 #cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@
 
+#cmakedefine USE_POSIX_SPAWN @USE_POSIX_SPAWN@
+
 /* SDL internal assertion support */
 #if @SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED@
 #cmakedefine SDL_DEFAULT_ASSERT_LEVEL @SDL_DEFAULT_ASSERT_LEVEL@

+ 3 - 4
love/src/jni/SDL2/include/SDL_config_android.h

@@ -143,10 +143,9 @@
 #endif
 
 /* Enable various audio drivers */
-/* love2d-mod: Audio is handled by OpenAL */
-#define SDL_AUDIO_DRIVER_ANDROID    0
-#define SDL_AUDIO_DRIVER_OPENSLES   0
-#define SDL_AUDIO_DRIVER_AAUDIO     0
+#define SDL_AUDIO_DRIVER_ANDROID    1
+#define SDL_AUDIO_DRIVER_OPENSLES   1
+#define SDL_AUDIO_DRIVER_AAUDIO     1
 #define SDL_AUDIO_DRIVER_DUMMY  1
 
 /* Enable various input drivers */

+ 1 - 1
love/src/jni/SDL2/include/SDL_version.h

@@ -59,7 +59,7 @@ typedef struct SDL_version
 */
 #define SDL_MAJOR_VERSION   2
 #define SDL_MINOR_VERSION   28
-#define SDL_PATCHLEVEL      3
+#define SDL_PATCHLEVEL      5
 
 /**
  * Macro to determine SDL version program was compiled against.

+ 10 - 2
love/src/jni/SDL2/src/SDL_assert.c

@@ -42,7 +42,15 @@
 #endif
 
 #if defined(__EMSCRIPTEN__)
-#include <emscripten.h>
+    #include <emscripten.h>
+    /* older Emscriptens don't have this, but we need to for wasm64 compatibility. */
+    #ifndef MAIN_THREAD_EM_ASM_PTR
+        #ifdef __wasm64__
+            #error You need to upgrade your Emscripten compiler to support wasm64
+        #else
+            #define MAIN_THREAD_EM_ASM_PTR MAIN_THREAD_EM_ASM_INT
+        #endif
+    #endif
 #endif
 
 /* The size of the stack buffer to use for rendering assert messages. */
@@ -251,7 +259,7 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data,
         for (;;) {
             SDL_bool okay = SDL_TRUE;
             /* *INDENT-OFF* */ /* clang-format off */
-            char *buf = (char *) EM_ASM_INT({
+            char *buf = (char *) MAIN_THREAD_EM_ASM_PTR({
                 var str =
                     UTF8ToString($0) + '\n\n' +
                     'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :';

+ 2 - 2
love/src/jni/SDL2/src/audio/arts/SDL_artsaudio.c

@@ -300,12 +300,12 @@ static void ARTS_Deinitialize(void)
 }
 
 
-static SDL_bool ARTS_Init(SDL_AudioDriverImpl * impl)
+static SDL_bool ARTS_Init(SDL_AudioDriverImpl *impl)
 {
     if (LoadARTSLibrary() < 0) {
         return SDL_FALSE;
     } else {
-        if (SDL_NAME(arts_init) () != NULL) {
+        if (SDL_NAME(arts_init) () != 0) {
             UnloadARTSLibrary();
             SDL_SetError("ARTS: arts_init failed (no audio server?)");
             return SDL_FALSE;

+ 2 - 0
love/src/jni/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c

@@ -197,6 +197,8 @@ static void EMSCRIPTENAUDIO_CloseDevice(_THIS)
 #endif
 }
 
+EM_JS_DEPS(sdlaudio, "$autoResumeAudioContext,$dynCall");
+
 static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
 {
     SDL_AudioFormat test_format;

+ 2 - 0
love/src/jni/SDL2/src/audio/qsa/SDL_qsa_audio.c

@@ -233,6 +233,7 @@ static Uint8 *QSA_GetDeviceBuf(_THIS)
 static void QSA_CloseDevice(_THIS)
 {
     if (this->hidden->audio_handle != NULL) {
+#if _NTO_VERSION < 710
         if (!this->iscapture) {
             /* Finish playing available samples */
             snd_pcm_plugin_flush(this->hidden->audio_handle,
@@ -242,6 +243,7 @@ static void QSA_CloseDevice(_THIS)
             snd_pcm_plugin_flush(this->hidden->audio_handle,
                                  SND_PCM_CHANNEL_CAPTURE);
         }
+#endif
         snd_pcm_close(this->hidden->audio_handle);
     }
 

+ 2 - 2
love/src/jni/SDL2/src/core/android/SDL_android.c

@@ -1939,12 +1939,12 @@ int Android_JNI_FileOpen(SDL_RWops *ctx,
     }
 
     if (asset_manager == NULL) {
-        return -1;
+        return SDL_SetError("Couldn't create asset manager");
     }
 
     asset = AAssetManager_open(asset_manager, fileName, AASSET_MODE_UNKNOWN);
     if (asset == NULL) {
-        return -1;
+        return SDL_SetError("Couldn't open asset '%s'", fileName);
     }
 
     ctx->hidden.androidio.asset = (void *)asset;

+ 1 - 0
love/src/jni/SDL2/src/hidapi/libusb/hid.c

@@ -711,6 +711,7 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de
 	static const int XB1_IFACE_SUBCLASS = 71;
 	static const int XB1_IFACE_PROTOCOL = 208;
 	static const int SUPPORTED_VENDORS[] = {
+        0x03f0, /* HP */
 		0x044f, /* Thrustmaster */
 		0x045e, /* Microsoft */
 		0x0738, /* Mad Catz */

+ 18 - 0
love/src/jni/SDL2/src/joystick/SDL_joystick.c

@@ -2479,8 +2479,11 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
         MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */
         MAKE_VIDPID(0x046d, 0xc268), /* Logitech PRO Racing Wheel (PC mode) */
         MAKE_VIDPID(0x046d, 0xc269), /* Logitech PRO Racing Wheel (PS4/PS5 mode) */
+        MAKE_VIDPID(0x046d, 0xc272), /* Logitech PRO Racing Wheel for Xbox (PC mode) */
         MAKE_VIDPID(0x046d, 0xc26d), /* Logitech G923 (Xbox) */
         MAKE_VIDPID(0x046d, 0xc26e), /* Logitech G923 */
+        MAKE_VIDPID(0x046d, 0xc266), /* Logitech G923 for Playstation 4 and PC (PC mode) */
+        MAKE_VIDPID(0x046d, 0xc267), /* Logitech G923 for Playstation 4 and PC (PS4 mode)*/
         MAKE_VIDPID(0x046d, 0xca03), /* Logitech Momo Racing */
         MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
         MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
@@ -2492,7 +2495,22 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
         MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */
         MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */
         MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */
+        MAKE_VIDPID(0x0483, 0x0522), /* Simagic Wheelbase (including M10, Alpha Mini, Alpha, Alpha U) */
+        MAKE_VIDPID(0x0eb7, 0x0001), /* Fanatec ClubSport Wheel Base V2 */
+        MAKE_VIDPID(0x0eb7, 0x0004), /* Fanatec ClubSport Wheel Base V2.5 */
+        MAKE_VIDPID(0x0eb7, 0x0005), /* Fanatec CSL Elite Wheel Base+ (PS4) */
+        MAKE_VIDPID(0x0eb7, 0x0006), /* Fanatec Podium Wheel Base DD1 */
+        MAKE_VIDPID(0x0eb7, 0x0007), /* Fanatec Podium Wheel Base DD2 */
+        MAKE_VIDPID(0x0eb7, 0x0011), /* Fanatec Forza Motorsport (CSR Wheel / CSR Elite Wheel) */
+        MAKE_VIDPID(0x0eb7, 0x0020), /* Fanatec generic wheel / CSL DD / GT DD Pro */
+        MAKE_VIDPID(0x0eb7, 0x0197), /* Fanatec Porsche Wheel (Turbo / GT3 RS / Turbo S / GT3 V2 / GT2) */
+        MAKE_VIDPID(0x0eb7, 0x038e), /* Fanatec ClubSport Wheel Base V1 */
+        MAKE_VIDPID(0x0eb7, 0x0e03), /* Fanatec CSL Elite Wheel Base */
         MAKE_VIDPID(0x11ff, 0x0511), /* DragonRise Inc. Wired Wheel (initial mode) (also known as PXN V900 (PS3), Superdrive SV-750, or a Genesis Seaborg 400) */
+        MAKE_VIDPID(0x2433, 0xf300), /* Asetek SimSports Invicta Wheelbase */
+        MAKE_VIDPID(0x2433, 0xf301), /* Asetek SimSports Forte Wheelbase */
+        MAKE_VIDPID(0x2433, 0xf303), /* Asetek SimSports La Prima Wheelbase */
+        MAKE_VIDPID(0x2433, 0xf306), /* Asetek SimSports Tony Kannan Wheelbase */
     };
     int i;
 

+ 1 - 0
love/src/jni/SDL2/src/joystick/controller_list.h

@@ -294,6 +294,7 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafd ), k_eControllerType_XBox360Controller, NULL },	// Afterglow Gamepad 3
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafe ), k_eControllerType_XBox360Controller, NULL },	// Rock Candy Gamepad for Xbox 360
 
+	{ MAKE_CONTROLLER_ID( 0x03f0, 0x0495 ), k_eControllerType_XBoxOneController, NULL },	// HP HyperX Clutch Gladiate
 	{ MAKE_CONTROLLER_ID( 0x044f, 0xd012 ), k_eControllerType_XBoxOneController, NULL },	// ThrustMaster eSwap PRO Controller Xbox
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x02d1 ), k_eControllerType_XBoxOneController, "Xbox One Controller" },	// Microsoft X-Box One pad
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x02dd ), k_eControllerType_XBoxOneController, "Xbox One Controller" },	// Microsoft X-Box One pad (Firmware 2015)

+ 48 - 20
love/src/jni/SDL2/src/joystick/hidapi/SDL_hidapi_ps5.c

@@ -102,7 +102,7 @@ typedef struct
     Uint8 rgucAccelX[2];          /* 21 */
     Uint8 rgucAccelY[2];          /* 23 */
     Uint8 rgucAccelZ[2];          /* 25 */
-    Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
+    Uint8 rgucSensorTimestamp[4]; /* 27 - 16/32 bit little endian */
 
 } PS5StatePacketCommon_t;
 
@@ -154,7 +154,9 @@ typedef struct
     Uint8 rgucAccelX[2];          /* 21 */
     Uint8 rgucAccelY[2];          /* 23 */
     Uint8 rgucAccelZ[2];          /* 25 */
-    Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
+    Uint8 rgucSensorTimestamp[2]; /* 27 - 16 bit little endian */
+    Uint8 ucBatteryLevel;         /* 29 */
+    Uint8 ucUnknown;              /* 30 */
     Uint8 ucTouchpadCounter1;     /* 31 - high bit clear + counter */
     Uint8 rgucTouchpadData1[3];   /* 32 - X/Y, 12 bits per axis */
     Uint8 ucTouchpadCounter2;     /* 35 - high bit clear + counter */
@@ -721,7 +723,7 @@ static void HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device)
     SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
     SDL_bool led_reset_complete = SDL_FALSE;
 
-    if (ctx->sensors_supported) {
+    if (ctx->enhanced_mode && ctx->sensors_supported && !ctx->use_alternate_report) {
         const PS5StatePacketCommon_t *packet = &ctx->last_state.state;
 
         /* Check the timer to make sure the Bluetooth connection LED animation is complete */
@@ -1229,30 +1231,56 @@ static void HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL
     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
 
     if (ctx->report_sensors) {
-        Uint32 timestamp;
-        Uint64 timestamp_us;
         float data[3];
+        Uint64 timestamp_us;
 
-        timestamp = LOAD32(packet->rgucSensorTimestamp[0],
-                           packet->rgucSensorTimestamp[1],
-                           packet->rgucSensorTimestamp[2],
-                           packet->rgucSensorTimestamp[3]);
-        if (ctx->timestamp) {
-            Uint32 delta;
+        if (ctx->use_alternate_report) {
+            /* 16-bit timestamp */
+            Uint16 timestamp;
 
-            if (ctx->last_timestamp > timestamp) {
-                delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1);
+            timestamp = LOAD16(packet->rgucSensorTimestamp[0],
+                               packet->rgucSensorTimestamp[1]);
+            if (ctx->timestamp) {
+                Uint16 delta;
+
+                if (ctx->last_timestamp > timestamp) {
+                    delta = (SDL_MAX_UINT16 - ctx->last_timestamp + timestamp + 1);
+                } else {
+                    delta = (timestamp - ctx->last_timestamp);
+                }
+                ctx->timestamp += delta;
             } else {
-                delta = (timestamp - ctx->last_timestamp);
+                ctx->timestamp = timestamp;
             }
-            ctx->timestamp += delta;
+            ctx->last_timestamp = timestamp;
+
+            /* Sensor timestamp is in 1us units */
+            timestamp_us = ctx->timestamp;
         } else {
-            ctx->timestamp = timestamp;
-        }
-        ctx->last_timestamp = timestamp;
+            /* 32-bit timestamp */
+            Uint32 timestamp;
+
+            timestamp = LOAD32(packet->rgucSensorTimestamp[0],
+                               packet->rgucSensorTimestamp[1],
+                               packet->rgucSensorTimestamp[2],
+                               packet->rgucSensorTimestamp[3]);
+            if (ctx->timestamp) {
+                Uint32 delta;
+
+                if (ctx->last_timestamp > timestamp) {
+                    delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1);
+                } else {
+                    delta = (timestamp - ctx->last_timestamp);
+                }
+                ctx->timestamp += delta;
+            } else {
+                ctx->timestamp = timestamp;
+            }
+            ctx->last_timestamp = timestamp;
 
-        /* Sensor timestamp is in 0.33us units */
-        timestamp_us = ctx->timestamp / 3;
+            /* Sensor timestamp is in 0.33us units */
+            timestamp_us = ctx->timestamp / 3;
+        }
 
         data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1]));
         data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1]));

+ 7 - 0
love/src/jni/SDL2/src/joystick/hidapi/SDL_hidapijoystick.c

@@ -265,6 +265,7 @@ static SDL_GameControllerType SDL_GetJoystickGameControllerProtocol(const char *
         interface_protocol == XBONE_IFACE_PROTOCOL) {
 
         static const int SUPPORTED_VENDORS[] = {
+            0x03f0, /* HP */
             0x044f, /* Thrustmaster */
             0x045e, /* Microsoft */
             0x0738, /* Mad Catz */
@@ -1436,6 +1437,12 @@ static int HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index)
     device->updating = SDL_FALSE;
     SDL_UnlockMutex(device->dev_lock);
 
+    /* UpdateDevice() may have called HIDAPI_JoystickDisconnected() if the device went away */
+    if (device->num_joysticks == 0) {
+        SDL_free(hwdata);
+        return SDL_SetError("HIDAPI device disconnected while opening");
+    }
+
     if (!device->driver->OpenJoystick(device, joystick)) {
         /* The open failed, mark this device as disconnected and update devices */
         HIDAPI_JoystickDisconnected(device, joystickID);

+ 1 - 1
love/src/jni/SDL2/src/joystick/linux/SDL_sysjoystick.c

@@ -1752,11 +1752,11 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
     /* We temporarily open the device to check how it's configured. Make
        a fake SDL_Joystick object to do so. */
     joystick = (SDL_Joystick *)SDL_calloc(sizeof(*joystick), 1);
-    joystick->magic = &SDL_joystick_magic;
     if (joystick == NULL) {
         SDL_OutOfMemory();
         return SDL_FALSE;
     }
+    joystick->magic = &SDL_joystick_magic;
     SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
 
     joystick->hwdata = (struct joystick_hwdata *)

+ 4 - 4
love/src/jni/SDL2/src/main/windows/version.rc

@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,28,3,0
- PRODUCTVERSION 2,28,3,0
+ FILEVERSION 2,28,5,0
+ PRODUCTVERSION 2,28,5,0
  FILEFLAGSMASK 0x3fL
  FILEFLAGS 0x0L
  FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
         BEGIN
             VALUE "CompanyName", "\0"
             VALUE "FileDescription", "SDL\0"
-            VALUE "FileVersion", "2, 28, 3, 0\0"
+            VALUE "FileVersion", "2, 28, 5, 0\0"
             VALUE "InternalName", "SDL\0"
             VALUE "LegalCopyright", "Copyright (C) 2023 Sam Lantinga\0"
             VALUE "OriginalFilename", "SDL2.dll\0"
             VALUE "ProductName", "Simple DirectMedia Layer\0"
-            VALUE "ProductVersion", "2, 28, 3, 0\0"
+            VALUE "ProductVersion", "2, 28, 5, 0\0"
         END
     END
     BLOCK "VarFileInfo"

+ 3 - 5
love/src/jni/SDL2/src/misc/emscripten/SDL_sysurl.c

@@ -23,13 +23,11 @@
 
 #include <emscripten/emscripten.h>
 
+EM_JS_DEPS(sdlsysurl, "$UTF8ToString");
+
 int SDL_SYS_OpenURL(const char *url)
 {
-    EM_ASM({
-        window.open(UTF8ToString($0), "_blank");
-    },
-           url);
-
+    EM_ASM(window.open(UTF8ToString($0), "_blank"), url);
     return 0;
 }
 

+ 13 - 0
love/src/jni/SDL2/src/misc/unix/SDL_sysurl.c

@@ -32,6 +32,18 @@ int SDL_SYS_OpenURL(const char *url)
 {
     const pid_t pid1 = fork();
     if (pid1 == 0) { /* child process */
+#ifdef USE_POSIX_SPAWN
+        pid_t pid2;
+        const char *args[] = { "xdg-open", url, NULL };
+        /* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */
+        unsetenv("LD_PRELOAD");
+        if (posix_spawnp(&pid2, args[0], NULL, NULL, (char **)args, environ) == 0) {
+            /* Child process doesn't wait for possibly-blocking grandchild. */
+            _exit(EXIT_SUCCESS);
+        } else {
+            _exit(EXIT_FAILURE);
+        }
+#else
         pid_t pid2;
         /* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */
         unsetenv("LD_PRELOAD");
@@ -46,6 +58,7 @@ int SDL_SYS_OpenURL(const char *url)
             /* Child process doesn't wait for possibly-blocking grandchild. */
             _exit(EXIT_SUCCESS);
         }
+#endif /* USE_POSIX_SPAWN */
     } else if (pid1 < 0) {
         return SDL_SetError("fork() failed: %s", strerror(errno));
     } else {

+ 1 - 1
love/src/jni/SDL2/src/render/SDL_render.c

@@ -2481,7 +2481,7 @@ int SDL_RenderSetClipRect(SDL_Renderer *renderer, const SDL_Rect *rect)
     int retval;
     CHECK_RENDERER_MAGIC(renderer, -1)
 
-    if (rect && rect->w > 0 && rect->h > 0) {
+    if (rect && rect->w >= 0 && rect->h >= 0) {
         renderer->clipping_enabled = SDL_TRUE;
         renderer->clip_rect.x = (double)rect->x * renderer->scale.x;
         renderer->clip_rect.y = (double)rect->y * renderer->scale.y;

+ 13 - 8
love/src/jni/SDL2/src/render/software/SDL_triangle.c

@@ -789,15 +789,20 @@ static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
                 continue;
             }
         }
-        if (FORMAT_HAS_ALPHA(dstfmt_val)) {
-            DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
-        } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
-            DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
-            dstA = 0xFF;
+        if ((flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL))) {
+            if (FORMAT_HAS_ALPHA(dstfmt_val)) {
+                DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
+            } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
+                DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
+                dstA = 0xFF;
+            } else {
+                /* SDL_PIXELFORMAT_ARGB2101010 */
+                dstpixel = *((Uint32 *) (dst));
+                RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
+            }
         } else {
-            /* SDL_PIXELFORMAT_ARGB2101010 */
-            dstpixel = *((Uint32 *)(dst));
-            RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
+            /* don't care */
+            dstR = dstG = dstB = dstA = 0;
         }
 
         if (!is_uniform) {

+ 6 - 10
love/src/jni/SDL2/src/stdlib/SDL_iconv.c

@@ -795,17 +795,13 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inb
     size_t outbytesleft;
     size_t retCode = 0;
 
-    cd = SDL_iconv_open(tocode, fromcode);
-    if (cd == (SDL_iconv_t)-1) {
-        /* See if we can recover here (fixes iconv on Solaris 11) */
-        if (tocode == NULL || !*tocode) {
-            tocode = "UTF-8";
-        }
-        if (fromcode == NULL || !*fromcode) {
-            fromcode = "UTF-8";
-        }
-        cd = SDL_iconv_open(tocode, fromcode);
+    if (tocode == NULL || !*tocode) {
+        tocode = "UTF-8";
+    }
+    if (fromcode == NULL || !*fromcode) {
+        fromcode = "UTF-8";
     }
+    cd = SDL_iconv_open(tocode, fromcode);
     if (cd == (SDL_iconv_t)-1) {
         return NULL;
     }

+ 71 - 0
love/src/jni/SDL2/src/stdlib/SDL_string.c

@@ -1114,6 +1114,39 @@ int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
     return vsscanf(text, fmt, ap);
 }
 #else
+static SDL_bool CharacterMatchesSet(char c, const char *set, size_t set_len)
+{
+    SDL_bool invert = SDL_FALSE;
+    SDL_bool result = SDL_FALSE;
+
+    if (*set == '^') {
+        invert = SDL_TRUE;
+        ++set;
+        --set_len;
+    }
+    while (set_len > 0 && !result) {
+        if (set_len >= 3 && set[1] == '-') {
+            char low_char = SDL_min(set[0], set[2]);
+            char high_char = SDL_max(set[0], set[2]);
+            if (c >= low_char && c <= high_char) {
+                result = SDL_TRUE;
+            }
+            set += 3;
+            set_len -= 3;
+        } else {
+            if (c == *set) {
+                result = SDL_TRUE;
+            }
+            ++set;
+            --set_len;
+        }
+    }
+    if (invert) {
+        result = result ? SDL_FALSE : SDL_TRUE;
+    }
+    return result;
+}
+
 /* NOLINTNEXTLINE(readability-non-const-parameter) */
 int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
 {
@@ -1387,6 +1420,44 @@ int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
                     }
                     done = SDL_TRUE;
                     break;
+                case '[':
+                {
+                    const char *set = fmt + 1;
+                    while (*fmt && *fmt != ']') {
+                        ++fmt;
+                    }
+                    if (*fmt) {
+                        size_t set_len = (fmt - set);
+                        if (suppress) {
+                            while (CharacterMatchesSet(*text, set, set_len)) {
+                                ++text;
+                                if (count) {
+                                    if (--count == 0) {
+                                        break;
+                                    }
+                                }
+                            }
+                        } else {
+                            SDL_bool had_match = SDL_FALSE;
+                            char *valuep = va_arg(ap, char *);
+                            while (CharacterMatchesSet(*text, set, set_len)) {
+                                had_match = SDL_TRUE;
+                                *valuep++ = *text++;
+                                if (count) {
+                                    if (--count == 0) {
+                                        break;
+                                    }
+                                }
+                            }
+                            *valuep = '\0';
+                            if (had_match) {
+                                ++retval;
+                            }
+                        }
+                    }
+                }
+                    done = SDL_TRUE;
+                    break;
                 default:
                     done = SDL_TRUE;
                     break;

+ 24 - 2
love/src/jni/SDL2/src/test/SDL_test_compare.c

@@ -36,6 +36,25 @@
 /* Counter for _CompareSurface calls; used for filename creation when comparisons fail */
 static int _CompareSurfaceCount = 0;
 
+static Uint32
+GetPixel(Uint8 *p, size_t bytes_per_pixel)
+{
+    Uint32 ret = 0;
+
+    SDL_assert(bytes_per_pixel <= sizeof(ret));
+
+    /* Fill the appropriate number of least-significant bytes of ret,
+     * leaving the most-significant bytes set to zero, so that ret can
+     * be decoded with SDL_GetRGBA afterwards. */
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+    SDL_memcpy(((Uint8 *) &ret) + (sizeof(ret) - bytes_per_pixel), p, bytes_per_pixel);
+#else
+    SDL_memcpy(&ret, p, bytes_per_pixel);
+#endif
+
+    return ret;
+}
+
 /* Compare surfaces */
 int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error)
 {
@@ -74,11 +93,14 @@ int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface,
     /* Compare image - should be same format. */
     for (j = 0; j < surface->h; j++) {
         for (i = 0; i < surface->w; i++) {
+            Uint32 pixel;
             p = (Uint8 *)surface->pixels + j * surface->pitch + i * bpp;
             p_reference = (Uint8 *)referenceSurface->pixels + j * referenceSurface->pitch + i * bpp_reference;
 
-            SDL_GetRGBA(*(Uint32 *)p, surface->format, &R, &G, &B, &A);
-            SDL_GetRGBA(*(Uint32 *)p_reference, referenceSurface->format, &Rd, &Gd, &Bd, &Ad);
+            pixel = GetPixel(p, bpp);
+            SDL_GetRGBA(pixel, surface->format, &R, &G, &B, &A);
+            pixel = GetPixel(p_reference, bpp_reference);
+            SDL_GetRGBA(pixel, referenceSurface->format, &Rd, &Gd, &Bd, &Ad);
 
             dist = 0;
             dist += (R - Rd) * (R - Rd);

+ 3 - 1
love/src/jni/SDL2/src/test/SDL_test_fuzzer.c

@@ -471,7 +471,9 @@ char *SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
     }
 
     size = (SDLTest_RandomUint32() % (maxLength + 1));
-
+    if (size == 0) {
+        size = 1;
+    }
     return SDLTest_RandomAsciiStringOfSize(size);
 }
 

+ 13 - 8
love/src/jni/SDL2/src/video/SDL_blit_slow.c

@@ -106,15 +106,20 @@ void SDL_Blit_Slow(SDL_BlitInfo *info)
                     continue;
                 }
             }
-            if (FORMAT_HAS_ALPHA(dstfmt_val)) {
-                DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
-            } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
-                DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
-                dstA = 0xFF;
+            if ((flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL))) {
+                if (FORMAT_HAS_ALPHA(dstfmt_val)) {
+                    DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
+                } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
+                    DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
+                    dstA = 0xFF;
+                } else {
+                    /* SDL_PIXELFORMAT_ARGB2101010 */
+                    dstpixel = *((Uint32 *) (dst));
+                    RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
+                }
             } else {
-                /* SDL_PIXELFORMAT_ARGB2101010 */
-                dstpixel = *((Uint32 *)(dst));
-                RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
+                /* don't care */
+                dstR = dstG = dstB = dstA = 0;
             }
 
             if (flags & SDL_COPY_MODULATE_COLOR) {

+ 1 - 0
love/src/jni/SDL2/src/video/android/SDL_androidevents.c

@@ -74,6 +74,7 @@ static void android_egl_context_restore(SDL_Window *window)
     if (window) {
         SDL_Event event;
         SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+        SDL_GL_MakeCurrent(window, NULL);
         if (SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context) < 0) {
             /* The context is no longer valid, create a new one */
             data->egl_context = (EGLContext)SDL_GL_CreateContext(window);

+ 12 - 1
love/src/jni/SDL2/src/video/emscripten/SDL_emscriptenmouse.c

@@ -31,6 +31,15 @@
 
 #include "../../events/SDL_mouse_c.h"
 
+/* older Emscriptens don't have this, but we need to for wasm64 compatibility. */
+#ifndef MAIN_THREAD_EM_ASM_PTR
+    #ifdef __wasm64__
+        #error You need to upgrade your Emscripten compiler to support wasm64
+    #else
+        #define MAIN_THREAD_EM_ASM_PTR MAIN_THREAD_EM_ASM_INT
+    #endif
+#endif
+
 static SDL_Cursor *Emscripten_CreateCursorFromString(const char *cursor_str, SDL_bool is_custom)
 {
     SDL_Cursor *cursor;
@@ -60,6 +69,8 @@ static SDL_Cursor *Emscripten_CreateDefaultCursor()
     return Emscripten_CreateCursorFromString("default", SDL_FALSE);
 }
 
+EM_JS_DEPS(sdlmouse, "$stringToUTF8,$UTF8ToString");
+
 static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
 {
     const char *cursor_url = NULL;
@@ -72,7 +83,7 @@ static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int
     }
 
     /* *INDENT-OFF* */ /* clang-format off */
-    cursor_url = (const char *)MAIN_THREAD_EM_ASM_INT({
+    cursor_url = (const char *)MAIN_THREAD_EM_ASM_PTR({
         var w = $0;
         var h = $1;
         var hot_x = $2;

+ 8 - 2
love/src/jni/SDL2/src/video/wayland/SDL_waylandevents.c

@@ -2534,6 +2534,10 @@ static void lock_pointer_to_window(SDL_Window *window,
     SDL_VideoData *d = input->display;
     struct zwp_locked_pointer_v1 *locked_pointer;
 
+    if (!d->pointer_constraints || !input->pointer) {
+        return;
+    }
+
     if (w->locked_pointer) {
         return;
     }
@@ -2621,8 +2625,10 @@ int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
         w->locked_pointer = NULL;
     }
 
-    zwp_relative_pointer_v1_destroy(input->relative_pointer);
-    input->relative_pointer = NULL;
+    if (input->relative_pointer) {
+        zwp_relative_pointer_v1_destroy(input->relative_pointer);
+        input->relative_pointer = NULL;
+    }
 
     d->relative_mouse_mode = 0;
 

+ 10 - 16
love/src/jni/SDL2/src/video/wayland/SDL_waylandwindow.c

@@ -1322,21 +1322,15 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
     /* Create the shell surface and map the toplevel/popup */
 #ifdef HAVE_LIBDECOR_H
     if (data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
-        if (data->shell_surface.libdecor.frame) {
-            /* If the frame already exists, just set the visibility. */
-            libdecor_frame_set_visibility(data->shell_surface.libdecor.frame, true);
-            libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
+        data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor,
+                                                               data->surface,
+                                                               &libdecor_frame_interface,
+                                                               data);
+        if (data->shell_surface.libdecor.frame == NULL) {
+            SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!");
         } else {
-            data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor,
-                                                                   data->surface,
-                                                                   &libdecor_frame_interface,
-                                                                   data);
-            if (data->shell_surface.libdecor.frame == NULL) {
-                SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!");
-            } else {
-                libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
-                libdecor_frame_map(data->shell_surface.libdecor.frame);
-            }
+            libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
+            libdecor_frame_map(data->shell_surface.libdecor.frame);
         }
     } else
 #endif
@@ -1540,8 +1534,8 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
 #ifdef HAVE_LIBDECOR_H
     if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
         if (wind->shell_surface.libdecor.frame) {
-            libdecor_frame_set_visibility(wind->shell_surface.libdecor.frame, false);
-            libdecor_frame_set_app_id(wind->shell_surface.libdecor.frame, data->classname);
+            libdecor_frame_unref(wind->shell_surface.libdecor.frame);
+            wind->shell_surface.libdecor.frame = NULL;
         }
     } else
 #endif

+ 1 - 4
love/src/jni/SDL2/src/video/x11/SDL_x11clipboard.c

@@ -132,10 +132,7 @@ static int SetSelectionText(_THIS, const char *text, Atom selection_type)
                         X11_GetSDLCutBufferClipboardInternalFormat(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING), 8, PropModeReplace,
                         (const unsigned char *)text, SDL_strlen(text));
 
-    if (X11_XGetSelectionOwner(display, selection_type) != window) {
-        X11_XSetSelectionOwner(display, selection_type, window, CurrentTime);
-    }
-
+    X11_XSetSelectionOwner(display, selection_type, window, CurrentTime);
     return 0;
 }
 

+ 11 - 18
love/src/jni/SDL2/src/video/x11/SDL_x11mouse.c

@@ -330,13 +330,16 @@ static void WarpMouseInternal(Window xwindow, const int x, const int y)
     Display *display = videodata->display;
 #if SDL_VIDEO_DRIVER_X11_XINPUT2
     int deviceid = 0;
-    /* It seems XIWarpPointer() doesn't work correctly on multi-head setups:
-     * https://developer.blender.org/rB165caafb99c6846e53d11c4e966990aaffc06cea
-     */
-    if (ScreenCount(display) == 1) {
-        X11_XIGetClientPointer(display, None, &deviceid);
+    if (X11_Xinput2IsInitialized()) {
+        /* It seems XIWarpPointer() doesn't work correctly on multi-head setups:
+         * https://developer.blender.org/rB165caafb99c6846e53d11c4e966990aaffc06cea
+         */
+        if (ScreenCount(display) == 1) {
+            X11_XIGetClientPointer(display, None, &deviceid);
+        }
     }
     if (deviceid != 0) {
+        SDL_assert(SDL_X11_HAVE_XINPUT2);
         X11_XIWarpPointer(display, deviceid, None, xwindow, 0.0, 0.0, 0, 0, (double)x, (double)y);
     } else
 #endif
@@ -369,14 +372,7 @@ static int X11_WarpMouseGlobal(int x, int y)
 
 static int X11_SetRelativeMouseMode(SDL_bool enabled)
 {
-#if SDL_VIDEO_DRIVER_X11_XINPUT2
-    if (X11_Xinput2IsInitialized()) {
-        return 0;
-    }
-#else
-    SDL_Unsupported();
-#endif
-    return -1;
+    return X11_Xinput2IsInitialized() ? 0 : SDL_Unsupported();
 }
 
 static int X11_CaptureMouse(SDL_Window *window)
@@ -414,12 +410,9 @@ static Uint32 X11_GetGlobalMouseState(int *x, int *y)
 
     /* !!! FIXME: should we XSync() here first? */
 
-#if !SDL_VIDEO_DRIVER_X11_XINPUT2
-    videodata->global_mouse_changed = SDL_TRUE;
-#else
-    if (!SDL_X11_HAVE_XINPUT2)
+    if (!X11_Xinput2IsInitialized()) {
         videodata->global_mouse_changed = SDL_TRUE;
-#endif
+    }
 
     /* check if we have this cached since XInput last saw the mouse move. */
     /* !!! FIXME: can we just calculate this from XInput's events? */

+ 7 - 0
love/src/jni/SDL2/test/CMakeLists.txt

@@ -168,6 +168,9 @@ add_sdl_test_executable(testoverlay2 NEEDS_RESOURCES testoverlay2.c testyuv_cvt.
 add_sdl_test_executable(testplatform NONINTERACTIVE testplatform.c)
 add_sdl_test_executable(testpower NONINTERACTIVE testpower.c)
 add_sdl_test_executable(testfilesystem NONINTERACTIVE testfilesystem.c)
+if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+    add_sdl_test_executable(testfilesystem_pre NONINTERACTIVE testfilesystem_pre.c)
+endif()
 add_sdl_test_executable(testrendertarget NEEDS_RESOURCES testrendertarget.c testutils.c)
 add_sdl_test_executable(testscale NEEDS_RESOURCES testscale.c testutils.c)
 add_sdl_test_executable(testsem testsem.c)
@@ -426,6 +429,10 @@ endforeach()
 
 set_tests_properties(testthread PROPERTIES TIMEOUT 40)
 set_tests_properties(testtimer PROPERTIES TIMEOUT 60)
+if(TARGET testfilesystem_pre)
+    set_property(TEST testfilesystem_pre PROPERTY TIMEOUT 60)
+    set_property(TEST testfilesystem APPEND PROPERTY DEPENDS testfilesystem_pre)
+endif()
 
 if(SDL_INSTALL_TESTS)
     if(RISCOS)

+ 77 - 1
love/src/jni/SDL2/test/testautomation_stdlib.c

@@ -339,7 +339,7 @@ int stdlib_sscanf(void *arg)
     long long_output, expected_long_output;
     long long long_long_output, expected_long_long_output;
     size_t size_output, expected_size_output;
-    char text[128];
+    char text[128], text2[128];
 
     expected_output = output = 123;
     expected_result = -1;
@@ -403,6 +403,82 @@ int stdlib_sscanf(void *arg)
     SDLTest_AssertCheck(expected_size_output == size_output, "Check output, expected: %zu, got: %zu", expected_size_output, size_output);
     SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
 
+    expected_result = 1;
+    text[0] = '\0';
+    result = SDL_sscanf("abc def", "%s", text);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc def\", \"%%s\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 1;
+    text[0] = '\0';
+    result = SDL_sscanf("abc,def", "%s", text);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%s\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc,def") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 1;
+    text[0] = '\0';
+    result = SDL_sscanf("abc,def", "%[cba]", text);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[cba]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 1;
+    text[0] = '\0';
+    result = SDL_sscanf("abc,def", "%[a-z]", text);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[z-a]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 1;
+    text[0] = '\0';
+    result = SDL_sscanf("abc,def", "%[^,]", text);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[^,]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 0;
+    text[0] = '\0';
+    result = SDL_sscanf("abc,def", "%[A-Z]", text);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[A-Z]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "") == 0, "Check output, expected: \"\", got: \"%s\"", text);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 2;
+    text[0] = '\0';
+    text2[0] = '\0';
+    result = SDL_sscanf("abc,def", "%[abc],%[def]", text, text2);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[abc],%%[def]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(SDL_strcmp(text2, "def") == 0, "Check output, expected: \"def\", got: \"%s\"", text2);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 2;
+    text[0] = '\0';
+    text2[0] = '\0';
+    result = SDL_sscanf("abc,def", "%[abc]%*[,]%[def]", text, text2);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc,def\", \"%%[abc]%%*[,]%%[def]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(SDL_strcmp(text2, "def") == 0, "Check output, expected: \"def\", got: \"%s\"", text2);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 2;
+    text[0] = '\0';
+    text2[0] = '\0';
+    result = SDL_sscanf("abc   def", "%[abc] %[def]", text, text2);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc   def\", \"%%[abc] %%[def]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc") == 0, "Check output, expected: \"abc\", got: \"%s\"", text);
+    SDLTest_AssertCheck(SDL_strcmp(text2, "def") == 0, "Check output, expected: \"def\", got: \"%s\"", text2);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
+    expected_result = 1;
+    text[0] = '\0';
+    result = SDL_sscanf("abc123XYZ", "%[a-zA-Z0-9]", text);
+    SDLTest_AssertPass("Call to SDL_sscanf(\"abc123XYZ\", \"%%[a-zA-Z0-9]\", text)");
+    SDLTest_AssertCheck(SDL_strcmp(text, "abc123XYZ") == 0, "Check output, expected: \"abc123XYZ\", got: \"%s\"", text);
+    SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
+
     return TEST_COMPLETED;
 }
 

+ 32 - 0
love/src/jni/SDL2/test/testfilesystem_pre.c

@@ -0,0 +1,32 @@
+/*
+  Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely.
+*/
+/* Call SDL_GetPrefPath to warm the SHGetFolderPathW cache */
+
+/**
+ * We noticed frequent ci timeouts running testfilesystem on 32-bit Windows.
+ * Internally, this functions calls Shell32.SHGetFolderPathW.
+ */
+
+#include "SDL.h"
+
+int main(int argc, char *argv[])
+{
+    Uint64 start;
+    (void)argc;
+    (void)argv;
+    SDL_Init(0);
+    start = SDL_GetTicks();
+    SDL_GetPrefPath("libsdl", "test_filesystem");
+    SDL_Log("SDL_GetPrefPath took %" SDL_PRIu64 "ms", SDL_GetTicks() - start);
+    SDL_Quit();
+    return 0;
+}