Compare commits

...

702 Commits

Author SHA1 Message Date
Sam Lantinga
a8589a8422 Updated to version 3.2.24 for release 2025-10-02 10:52:32 -07:00
Simon McVittie
0bdaaf6c76 build: Prefix SDL- to revision from REVISION.txt
This makes it possible to get the version number of an unknown SDL binary
from `strings libSDL3.so.0 | grep SDL-`, like we could for SDL 2.

Resolves: https://github.com/libsdl-org/SDL/issues/14114
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 618b7b6c73)
2025-10-02 09:09:03 -07:00
Simon McVittie
390197d3aa build: Prefix version from git with SDL- rather than SDL3-
We can tell it's SDL 3 from the version number and git revision,
so there's no need to duplicate that in the prefix.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit d5b79418f4)
2025-10-02 09:09:03 -07:00
Mathieu Eyraud
9fafba49dc Zero-initialize SDL_GPUDevice
(cherry picked from commit 86da08b0be)
2025-10-01 07:23:41 -07:00
Victor Ilyushchenko
5d47efe7fb Fix Metal 3D texture upload stride calculation
Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
(cherry picked from commit a34d31322c)
2025-09-28 07:32:48 -07:00
Sam Lantinga
824234accc Fixed HIDAPI controller disconnect reading on multiple threads
If multiple threads are calling SDL_UpdateJoysticks(), then an overlapped read can be initiated on one thread (read_pending set to true) and GetOverlappedResult() called on another thread. This results in ERROR_OPERATION_ABORTED. This is harmless so we shouldn't return an error in this case, we'll just retry the read on the next call.

Fixes https://github.com/libsdl-org/SDL/issues/14033

(cherry picked from commit b2188b325d)
2025-09-25 10:41:52 -07:00
Frank Praznik
6519158ae5 wayland: Ignore bogus libdecor content sizes if an unmapped window is suspended
If a client takes a long time to present the first frame after creating the window, a configure event to set the suspended state may arrive with libdecor increasing the content size by the decoration dimensions, which should be ignored.

(cherry picked from commit 9d5d7010de)
2025-09-24 10:36:04 -04:00
Frank Praznik
00718d60d2 x11: Use the pending size for the min/max limits if a resize is in flight
Otherwise, an outdated size may be used, reverting the requested resize operation.

(cherry picked from commit 45480f5fe5)
2025-09-24 10:36:04 -04:00
Sam Lantinga
18c2e179ee Use the real window position on macOS
On newer MacBooks, the fullscreen window might be placed below the camera notch, so use the actual window position

Fixes https://github.com/libsdl-org/SDL/issues/10441

(cherry picked from commit 0a50058f7a)
2025-09-23 23:04:41 -07:00
Sam Lantinga
21ae008fc2 Use an empty bitmap for the blank cursor on macOS
Some macOS installations seem to have trouble decoding the GIF we were using

Fixes https://github.com/libsdl-org/SDL/issues/14012

(cherry picked from commit 221d1f12ea)
2025-09-22 19:16:01 -07:00
Sam Lantinga
97a8bb44e6 The default swap interval on EGL is 1, according to the spec
Fixes https://github.com/libsdl-org/SDL/issues/14014

(cherry picked from commit 137b0b2bee)
2025-09-22 11:28:46 -07:00
Ryan C. Gordon
5d33fce898 wav: Patched to compile on Visual Studio.
(cherry picked from commit 09ee8876b3)
2025-09-22 08:14:33 -07:00
Ryan C. Gordon
bb5df96f69 wav: Clamp DATA chunk to size of file if possible.
Prevents a malicious file from malloc'ing multiple gigabytes.

Fixes #10052.

(cherry picked from commit 44e4deab7c)
2025-09-22 08:14:33 -07:00
Brenton Bostick
12b97944f3 fix: Extra parameter(s) for call to 'getCacheDir()'.
(cherry picked from commit 6590a5bc0b)
2025-09-22 07:25:19 -07:00
Brenton Bostick
0f17fbe1ca fix 'SDL_MessageBoxFlags' is not a valid JVM type.
(cherry picked from commit ed7d39b28c)
2025-09-22 07:05:05 -07:00
Sam Lantinga
c3480ca99c Use clearPrimaryClip() on Android 9 and newer
Fixes https://github.com/libsdl-org/SDL/issues/8355

(cherry picked from commit 34b09be6a5)
2025-09-21 23:30:57 -07:00
Sam Lantinga
936d94c2ee Fixed SDL_RunOnMainThread() on Android
If the application is waiting in SDL_WaitEvent(), we still need to run event loop maintenance in between calls to Android_PumpEvents().

Fixes the testautomation events_mainThreadCallbacks() test on Android.

(cherry picked from commit bae34c3e34)
2025-09-21 13:58:51 -07:00
Sam Lantinga
6cb55ebd46 Fixed a memory leak in fill_device_info_usage() (thanks @digant73)
Fixes https://github.com/libsdl-org/SDL/issues/13998

(cherry picked from commit 5503fe1c1b)
2025-09-20 09:05:52 -07:00
Andrei Sabalenka
482c5130eb wayland: fix typo in xdg_positioner_set_anchor_rect
(cherry picked from commit bb2b39b8ea)
2025-09-20 08:54:18 -07:00
Anonymous Maarten
066bcc5204 ci: disable ccache on macOS 13 job
(cherry picked from commit 566e7c2379)
2025-09-17 22:06:16 +02:00
ManifoldFR
21baa27bea gpu/vulkan : fix clear value indexing
(cherry picked from commit 8bc4e029bd)
2025-09-16 08:45:56 -07:00
Sora
93fd4a1c80 fix: use productCategory instead of vendorName for joy name for apple driver
(cherry picked from commit 964bedfdd9)
2025-09-15 11:52:21 -07:00
Ozkan Sezer
7135779599 SDL_endian.h: don't add _m_prefetch hack for clang-cl if available as a builtin
Fixes: https://github.com/libsdl-org/SDL/issues/13952 .

(cherry picked from commit 81f2f44843)
2025-09-15 20:10:28 +03:00
Eddy Jansson
62c151d044 wayland: Silence unused variable warning
'vd' and 'd' are only used if SDL_USE_LIBDBUS is set.

(cherry picked from commit 21c9f5304d)
2025-09-15 10:27:51 -04:00
Sam Lantinga
11d38fc23b Only use a transparent cursor on Windows when connected via RDP
VMware relies on the cursor being set to NULL to optimize relative mouse motion for games.

We should also revisit whether current RDP works better with a NULL cursor or a transparent cursor.

Fixes https://github.com/libsdl-org/SDL/issues/13700

(cherry picked from commit dac6af4ba6)
2025-09-14 17:31:09 -07:00
Sam Lantinga
d027f0ae6e Remove Windows 32-bit ARM build from CI
This architecture is deprecated and is now failing with:
Windows SDK 10.0.22621.0 : 'C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\um' not found or was incomplete

Fixes https://github.com/libsdl-org/SDL/issues/13949

(cherry picked from commit cc3274b6f1)
2025-09-14 15:45:34 -07:00
Nintorch
44290c204e Fix HP Deluxe Webcam KQ246AA detected as joystick
(cherry picked from commit 556ee00fe3)
2025-09-14 15:40:40 -07:00
Sam Lantinga
0b69860af6 Fixed testprocess on 32-bit Windows
Previously the test would kill the child process while it was in the process of initializing (loading DLLs, etc) and this would cause the test to fail.

(cherry picked from commit 937b7e6aea)
2025-09-14 15:40:06 -07:00
Sam Lantinga
e7a1ae0ea5 Clarify why we ignore EINVAL when flushing a file descriptor
(cherry picked from commit a1d3fc1f50)
2025-09-14 15:39:53 -07:00
Sam Lantinga
7af36d6c40 Ignore errors flushing output on POSIX pipes
Fixes https://github.com/libsdl-org/SDL/issues/13116
Fixes https://github.com/libsdl-org/SDL/issues/13412

(cherry picked from commit e40d337a47)
2025-09-14 12:10:18 -07:00
Sam Lantinga
d1ae1163dd Wait briefly after enabling effects on DualSense controller
The rumble motors apparently take a short time to power up after enabling enhanced mode.

Fixes https://github.com/libsdl-org/SDL/issues/13909

(cherry picked from commit 1aba421bd3)
2025-09-14 10:00:40 -07:00
Sam Lantinga
b2cf5729b4 Disable Windows.Gaming.Input by default
The functionality is already covered by XInput and DirectInput, and Microsoft is recommending GameInput going forward.

Fixes https://github.com/libsdl-org/SDL/issues/13000

(cherry picked from commit 78a29d1670)
2025-09-14 08:52:43 -07:00
Sam Lantinga
11b8dd76db Fixed memory leak when using detached threads
Fixes https://github.com/libsdl-org/SDL/issues/13886

(cherry picked from commit ede86a1267)
2025-09-14 08:43:12 -07:00
Frank Praznik
56507a6122 x11: Use the SDL_WindowFlags type instead of Uint32
Uint32 can potentially truncate the flag value, as it is 64 bits in SDL3.

(cherry picked from commit 4561be89a5)
2025-09-13 15:45:43 -04:00
Evan Hemsley
8d4324cba2 GPU: Bump MAX_COLOR_TARGET_BINDINGS to 8 (#13937)
(cherry picked from commit fe314a1b8a)
2025-09-12 13:38:58 -07:00
Jaan Soulier
35408a2126 Fix reallocation of GPU renderer vertex buffer
(cherry picked from commit ed6a72a7fd)
2025-09-09 20:28:32 -07:00
Sam Lantinga
e5b9dfd181 Fixed setting SDL_PROP_TEXTURE_VULKAN_TEXTURE_NUMBER
(cherry picked from commit b7dba970e1)
2025-09-09 17:35:03 -07:00
eafton
e8a5d07e5e X11: Check for invalid opcodes in SHM error handler
(cherry picked from commit b59d6d49c3)
2025-09-09 10:59:58 -07:00
Luis Caceres
8c1daf0caf gpu/vulkan: Move dereference after null check
(cherry picked from commit 03d0c2ad74)
2025-09-08 09:50:09 -07:00
Sam Lantinga
ad2b211f75 Fixed pitch and chroma issues with the Vulkan planar YUV texture update functions
Fixes https://github.com/libsdl-org/SDL/issues/13734

(cherry picked from commit 466f93aee1)
2025-09-07 10:19:59 -07:00
Sam Lantinga
414ae344af Fixed rumble strength on DualSense Edge and Bluetooth connected controllers
Fixes https://github.com/libsdl-org/SDL/issues/13771

(cherry picked from commit 25d9096d41)
2025-09-06 11:53:55 -07:00
Adrian
71af2c020c Set preferredFrameRateRange in main callbacks CADisplayLink
(cherry picked from commit 01e6aceffc)
2025-09-06 10:13:44 -07:00
Aleksey Melekh
e755f50072 xbox: fix build
(cherry picked from commit 129c97f610)
2025-09-05 09:20:34 -07:00
Sam Lantinga
a0b8275e9c Fixed the perspective matrix calculation (thanks @KonkolyTamas!)
Fixes https://github.com/libsdl-org/SDL/issues/13867

(cherry picked from commit ea1a769322)
2025-09-04 06:07:28 -07:00
Cameron Cawley
ea362839b1 Remove unused PSP source files
(cherry picked from commit 42f571ea4b)
2025-09-03 15:20:00 -07:00
Sam Lantinga
e7dd5d841b Don't set SDL_SURFACE_LOCK_NEEDED until a surface is RLE encoded
Reference https://github.com/libsdl-org/sdl2-compat/issues/476

(cherry picked from commit 437d78499c)
2025-09-02 21:32:17 -07:00
Sam Lantinga
5594d03da0 Leave letterbox borders set to the frame clear color
Fixes https://github.com/libsdl-org/sdl2-compat/issues/483

(cherry picked from commit fbbc29159a)
2025-09-02 20:14:56 -07:00
Sam Lantinga
f2ae66b64f Set the texture scale and address mode when creating a texture
Fixes https://github.com/libsdl-org/sdl2-compat/issues/506

(cherry picked from commit ef19c72015)
2025-09-02 19:46:28 -07:00
Anonymous Maarten
393d99338f cmake: make SDL_CPU_xxx variable visible when using CMAKE_OSX_ARCHITECTURES
(cherry picked from commit ebb52973e1)
2025-09-02 23:00:10 +03:00
Ozkan Sezer
4d88280931 cmake: simd detection clean-up for Apple multi-arch configs.
(cherry picked from commit 83bb0f9105)
2025-09-02 22:35:32 +03:00
Anonymous Maarten
e8cc359b5e cmake: use 'TargetConditionals.h' on Apple for SIMD tests
(cherry picked from commit e15e2808f2)
2025-09-02 22:35:20 +03:00
Anonymous Maarten
3b4a198655 cmake: use APPLE in dep_option
expands to <nothing> on e.g. Windows, which will be interpreted as true by cmake_dependent_option.

(cherry picked from commit 1e7d3b51de)
2025-09-02 22:35:02 +03:00
Ethan Lee
03dd1520a3 gpu: VK_KHR_get_physical_device_properties2 can be optional
(cherry picked from commit 689049f8ec)
2025-09-02 09:53:59 -07:00
Sam Lantinga
a6fd74fa3b Fix crash when enumerating Steam Controllers
Closes https://github.com/libsdl-org/SDL/pull/13746
2025-09-02 08:42:16 -07:00
Sam Lantinga
03b36bac94 Updated to version 3.2.23 for development 2025-09-01 15:12:43 -07:00
Sam Lantinga
a96677bdf6 Updated to version 3.2.22 for release 2025-09-01 14:40:32 -07:00
Ryan C. Gordon
67f89d0a2b openslES: Patched to compile.
(whoops.)

(cherry picked from commit 7323104f97)
2025-09-01 11:10:33 -04:00
Ryan C. Gordon
f6de8877ec openslES: OpenSL ES on Android only supports two formats, limit to that.
(Three with the floating point extension, which we use.)

This is according to:

https://developer.android.com/ndk/guides/audio/opensl/opensl-for-android

Previously, this would accept a request for Sint8 or Sint32 and disaster
would ensue.

Fixes #13779.

(cherry picked from commit 0b2a003a35)
2025-09-01 10:31:05 -04:00
Ozkan Sezer
7c189b1f17 cmake: revert commit 5d1bbd9 and change sse4.2 test
clang doesn't support -mcrc32 until version 14.0, therefore drop -mcrc32
use in sse 4.2 test, and change it to check _mm_cmpgt_epi64() instead of
_mm_crc32_u32(). without this, sse4.2 check was failing with clang <= 13

Fixes https://github.com/libsdl-org/SDL/pull/12223

(cherry picked from commit 875653658a)
2025-08-31 03:20:40 +03:00
Sam Lantinga
a7947080c0 Fixed warnings building with Visual Studio
(cherry picked from commit 7c8df4ea52)
2025-08-30 10:16:11 -07:00
Sam Lantinga
08c82a3781 Fixed build
(cherry picked from commit 3cf2350f21)
2025-08-30 10:15:48 -07:00
Jordan Saunders
589aea50c2 Fix two uninitialized variables
Found when running in valgrind looking at another issue.

- RenderPass' depth_stencil_target
    Tripped in SDL_BindGPUFragmentSamplers when not binding a DS target

- VulkanCommandBuffer's swapchainRequested
    Tripped in VULKAN_Submit for the end transition barrier when
    creating an image. The field is only reset when reused, not on first
    use

(cherry picked from commit 265236d952)
2025-08-30 06:05:43 -07:00
Ozkan Sezer
72acd7c9df CI: add OpenBSD workflow
(cherry picked from commit c0e5fd55d2)
2025-08-30 14:22:24 +03:00
Frank Praznik
1a70d1158e fs: Fix OpenBSD path retrieval
Set the path start pointer to point to a valid string.

(cherry picked from commit fdfde42db1)
2025-08-30 14:21:24 +03:00
Frank Praznik
ae915c6516 wayland: Add a sigtimedwait() implementation for OpenBSD
sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it. Add a replacement implementation based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation

(cherry picked from commit 1049426a76)
2025-08-30 14:21:00 +03:00
Xander
54d573332e Add SDL_SENSOR_COUNT to SDL_SensorType
(cherry picked from commit dc7a3a1219)
2025-08-29 07:31:25 -07:00
Matthew Zavislak
0204a69f6b Add elf alignment check for Android artifacts (#13818)
(cherry picked from commit 4f11feb708)
2025-08-28 16:31:25 -07:00
Susko3
b2689ff76a Avoid checking for HAVE_POSIX_SPAWN on Android
This makes the CMake build closer to SDL_build_config_android.h
as both will now use SDL_PROCESS_DUMMY.

(cherry picked from commit cd21bbe796)
2025-08-28 04:10:16 -07:00
Ozkan Sezer
611940fb80 cmake: fall back to -Wconversion if -Wfloat-conversion isn't available
... during checks for valid isinf/isinff/isnan/isnanf macros.

(cherry picked from commit 98bed62259)
2025-08-27 22:20:37 +03:00
Nintorch
16c0329a2a Add Emscripten joystick rumble support
Adds support for Emscripten (Web) joystick rumble support via EM_ASM_INT macros and HTML5's Gamepad API.

(cherry picked from commit 1fbed16cb0)
2025-08-25 12:59:15 -07:00
Nintorch
2743716132 Allow Android to ignore unnecessary joysticks
Previously, SDL_ShouldIgnoreJoystick wasn't being called for Android, and fingerprint sensors were recognized as joysticks.

(cherry picked from commit 1af7dfb0a7)
2025-08-25 11:23:34 -07:00
Colin Kinloch
a744eee993 testffmpeg: avutil queue family version check
The `AVVulkanDeviceQueueFamily` struct was introduced by libavutil
59.34.100

(cherry picked from commit 81920b5db7)
2025-08-25 11:10:31 -07:00
Evan Hemsley
0e24267eb5 gpu: D3D12 only requires feature level 11_0 with Resource Binding Tier 2. (#13782)
We previously thought this wasn't possible because constant buffer offsets and
partial updates were unavailable, but we were reading the wrong table - this is
only the case for D3D11...

https://learn.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro

... while 12 doesn't list this feature at all:

https://learn.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels

We double checked and Jesse Natalie confirmed that this feature is required for
D3D12 even for 11_0 drivers. (Thanks Jesse!)

Additionally, D3D12 requires that UAVs are accessible from all shader stages,
meaning Tier 2 is enough to support the number of UAVs we need. Tier 1 could be
a property to lower the requirements, but that can be done later.
2025-08-22 14:07:58 -07:00
Wilson Jallet
f4d6043aa4 GPU: Fix Vulkan indexing error for resolve attachment refs (#13768)
(cherry picked from commit 03b14f5211)
2025-08-19 12:13:23 -07:00
Petar Popovic
9fb9bd31a3 emscripten tests: fix warning: uninitialized variable
(cherry picked from commit 45feacf608)
2025-08-13 17:01:31 -07:00
ChaseKnowlden
c3828bb0a3 Keep MSVC Flags Consistent across CMake runs
(cherry picked from commit 10478c59db)
2025-08-12 19:39:44 -07:00
Sam Lantinga
40371f0907 Support the "ambient" value for SDL_HINT_AUDIO_CATEGORY
Fixes https://github.com/libsdl-org/SDL/issues/13732

(cherry picked from commit 4725213eef)
2025-08-12 09:54:43 -07:00
Sylvain
94f9434564 Fixed bug #13493: Assertion failure at SDL_AddTouch with Android API 28
Java touch id should be -1 because it's reserved for internal SDL
synthetic events.
It should also not be 0, because this is SDL invalid value.

(cherry picked from commit 970c0bfe96)
2025-08-12 09:44:04 -07:00
Chase Knowlden
bfaf247d30 Update NDK version to 28 (#13729)
* Update NDK version to 28 and add 16kb page size linker flags to x86_64

* Remove Android Linker Options

16kb page size is now the default since NDK r28c

* Update Android CI to use NDK 28

(cherry picked from commit 6e422e5ff2)
2025-08-12 07:46:27 -07:00
Beyley Cardellio
2287c43b59 GPU: Hold submit lock before waiting for device idle
(cherry picked from commit e699f3dca1)
2025-08-10 07:22:19 -07:00
Petar Popovic
15cc0f5f91 linux/SDL_syshaptic.c:SDL_SYS_HapticStopAll(): Fix return on error
(cherry picked from commit 43f3991398)
2025-08-09 09:28:02 -07:00
Anonymous Maarten
68e0108b1c release: build aarch64 libraries with 16kiB page size
[ci skip]

(cherry picked from commit 7017fbaa8e)
2025-08-09 05:23:43 +02:00
Mohamed Shazan
7b3796bc39 SDL_TriggerBreakpoint() will default to __debugbreak() on MinGW toolchain on windows
(cherry picked from commit f4c124e4bf)
2025-08-08 16:21:15 -07:00
Petar Popovic
b5bc6d2cc4 SDL_SendJoystickVirtualSensorDataInner(): Fix max_sensor_events increment
(cherry picked from commit d9c20cfd0a)
2025-08-08 12:52:03 -07:00
Petar Popovic
0d1d4ea1f9 SDL_SetRenderDrawBlendMode(): Remove redundant param check
(cherry picked from commit b63c32e790)
2025-08-08 14:06:27 -04:00
Pino Toscano
1a48f897f2 ime: fcitx: use SDL_GetExeName() in GetAppName()
Use the existing SDL_GetExeName(), available for all the UNIX
platforms, in the internal GetAppName(); this has few advantanges:
- SDL_GetExeName() (and SDL_GetAppID() that builds on top of it) are
  used in various places already; since it caches the executable name,
  this may remove one extra read of the application name
- SDL_GetExeName() has a non-dummy implementation in more OSes than
  GetAppName(), thus providing a small improvement for this IME

As drive-by change: since SDL_GetExeName() provides a constant string,
there is no more need to allocate a new string in GetAppName(), which
is used as constant string anyway. Hence, return a constant string in
GetAppName() too.

(cherry picked from commit 248bcf6b29)
2025-08-07 13:58:27 -07:00
Simon McVittie
2b42789de6 Fix some typos detected by Debian's lintian QA tool
I assume the demoninator is a typo, rather than an indication that
someone has been playing too much Doom :-)

Signed-off-by: Simon McVittie <smcv@collabora.com>

(cherry picked from commit d83503f80e)
2025-08-07 13:55:44 -07:00
Simon McVittie
b9c1da10ba hints: Rephrase documentation to improve grammar
"This thing allows to do something" is not really grammatically correct.
The closest rephrasing would be "allows one to do something" or "allows
the user to do something", but I think the passive voice reads more
naturally here.

Detected by Debian's lintian QA tool.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 40b941c826)
2025-08-07 13:55:44 -07:00
cosmonaut
56f5a76696 GPU: Fix uninitialized value in Vulkan command buffer structure
(cherry picked from commit fe6b2161bf)
2025-08-07 13:42:16 -07:00
Sam Lantinga
c7e8977e60 Revert "Support Google Play 16 KB Page Size Requirement (#13470)"
This reverts commit edef6e66e9

If you need to support the Google Play 16 kiB page size requirement, the recommendation is to use NDK r28c or newer, which automatically aligns binaries correctly.
2025-08-07 11:41:43 -07:00
Pino Toscano
e6ba3612db SDL_endian.h: extend Linux way for GNU libc
The currently used way to determine the endianness (i.e. include
<endian.h> and use the __BYTE_ORDER macro) is provided in general by
GNU libc. Thus, extend that to any platform/OS based on GNU libc.

(cherry picked from commit 561c99ee11)
2025-08-06 16:13:44 -07:00
Frank Praznik
5e77fb314c win32: Use the current flags to determine if NCCALCSIZE is required
SDL_GetWindowFlags() also ORs in pending flags, whereas the current state is needed here, particularly when creating/showing a window.

(cherry picked from commit cd0c660dea)
2025-08-05 18:49:41 -04:00
Frank Praznik
1a2841deb1 win32: Use STYLE_BORDERLESS when showing a pending fullscreen window
In addition to hiding the border on bordered windows that will immediately become fullscreen, The combination of flags used in STYLE_BORDERLESS_WINDOWED will still show the borders on borderless windows if the initial window size exactly matches the desktop, so STYLE_BORDERLESS must be used instead.

(cherry picked from commit 90a023007f)
2025-08-05 15:59:06 -04:00
Mathieu Eyraud
688637eca8 Fix condition for setting HDR properties
(cherry picked from commit a05aca51ec)
2025-08-05 09:26:12 -07:00
Frank Praznik
85d1d70ca1 cocoa: Wait for fullscreen spaces transitions to complete if switching to an exclusive mode
If attempting to switch to an exclusive mode while a fullscreen spaces transition is active, wait until the transition is complete before trying to apply the changes, or the window can wind up in a weird, broken state if a mode switch occurs while in a fullscreen space.

(cherry picked from commit f44a98729c)
2025-08-05 12:17:01 -04:00
Frank Praznik
09356c709a Revert "cocoa: Don't re-enter a fullscreen space if leaving to enter an exclusive mode"
This reverts commit 07b9e86d02.

It turns out that the problem is elsewhere, related to needing to block mode changes until spaces transitions are complete.
2025-08-04 23:51:47 -04:00
Frank Praznik
07b9e86d02 cocoa: Don't re-enter a fullscreen space if leaving to enter an exclusive mode
Doing so can leave the window in a weird, offset state.

(cherry picked from commit ee8f2861e7)
2025-08-04 22:16:22 -04:00
Sam Lantinga
8e46e5d8b4 Updated to version 3.2.21 for development 2025-08-04 11:54:34 -07:00
Sam Lantinga
96292a5b46 Updated to version 3.2.20 for release 2025-08-04 09:58:55 -07:00
Petar Popovic
ffa618c00b SDL_LoadWAV_IO(): On error, set *audio_buf to NULL and *audio_len to 0
(cherry picked from commit 23e08f7807)
2025-08-03 13:44:37 -04:00
Petar Popovic
291b9b3c82 SDL_enabled_assert(): Use NULL istead of 0 to explicity initialize the pointer members of SDL_AssertData
(cherry picked from commit faf3bd9991)
2025-08-03 13:36:14 -04:00
Frank Praznik
ec45117f0f x11: Filter mouse wheel events from "Master" devices
Discard wheel events from "Master" devices to avoid duplicates, as wheel events are stateless and can't be deduplicated.

(cherry picked from commit 51ce3f8c8d)
2025-08-02 18:57:44 -04:00
Frank Praznik
0d7aff9c56 GPU: Vulkan backend flags command buffer for cleanup when swapchain is requested
When skipping presentation due to the window being hidden, presentDataCount is not incremented on the command buffer, and subsequently the submitted command buffers will not be cleaned up as long as the window is hidden. This results in a lag spike when showing the window due to all previously submitted command buffers suddenly being cleaned up at once, and lag at shutdown due to an equivalent number of fences needing to be destroyed.

Instead of relying on presentDataCount to determine whether a command buffer should be cleaned up, use a flag, which is set under the appropriate circumstances.

(cherry picked from commit 42463569d5)
2025-08-02 09:24:21 -07:00
Petar Popovic
d31b239288 Fix double-free warning in src/hidapi/linux/hid.c
(cherry picked from commit ae5ce258cf)
2025-08-02 07:09:12 -07:00
capehill
b1cadf0e99 Fix SDL_BlitSurfaceScaled crash
SDL_BlitSurfaceScaled could crash when passed large coordinates, due
to final_dst.w or final_dst.h getting negative values.

(cherry picked from commit 1c5c3b1479)
2025-08-01 09:22:38 -07:00
Frank Praznik
c1f67585e6 wayland: Cleanup an outdated conditional and comment
There may have been a reason for not attaching a null buffer when destroying a popup at some point in the past, but that is unnecessary now, as is the comment about ShowWindow crashing, as ShowWindow assures that a null buffer is attached before (re)creating the window.

(cherry picked from commit 550d95e04f)
2025-08-01 10:40:32 -04:00
A1029384756
93988e28c0 wayland: reorder surface destruction to avoid premature blanking
(cherry picked from commit 9034375d2f)
2025-08-01 10:40:32 -04:00
Matthew Zavislak
edef6e66e9 Support Google Play 16 KB Page Size Requirement (#13470)
- See: https://developer.android.com/guide/practices/page-sizes#update-packaging
- Also, make min API uniform at 21 (from 16 and 23 in a few places)

(cherry picked from commit dc2c83c383)
2025-07-31 16:21:02 -07:00
Petar Popovic
e3f47809c4 Fix potential memory leak in SDL_render_gles2.c
(cherry picked from commit 09221820f6)
2025-07-31 16:19:10 -07:00
cosmonaut
f759e7ac59 GPU: Bail out of aquiring Vulkan swapchain if window is hidden
(cherry picked from commit c5edf4bd5b)
2025-07-31 16:03:19 -07:00
Frank Praznik
544eb2c5a9 wayland: Adjust popup adjoining check
The previous calculation could result in a window whose original position was positioned exactly corner-to-corner with the parent not being adjusted to be adjoining, and thus subject to spurious closure.

(cherry picked from commit b0cdb7143f)
2025-07-31 12:13:54 -04:00
Cheney Wang
30e3eba20a GPU: Fix wrong Vulkan swapchain size when retrying acquire
(cherry picked from commit d8ac51859e)
2025-07-30 15:35:23 -07:00
Wouter Wijsman
f0e85a2a9c psp: fix audio not playing
(cherry picked from commit 3d1a28ccf2)
2025-07-30 13:11:23 -07:00
Thaddeus Crews
106af5b46a Define relevant macros when LACKS_ERRNO_H is true
(cherry picked from commit 3195980b49)
2025-07-30 09:11:22 -07:00
Stefan Schlosser
522716ed90 SDL_getenv.c: fix dynamic loading of environ symbol on FreeBSD
The current implementation uses the returned address of the `dlsym` function
directly to load the `environ` symbol. But this function doesn't return the
address to the symbol itself, instead it returns the address to the location
where the actual address is stored, i.e. it's an additional indirection.
Consequently, the implementation fails to load and process the environment
variables successfully.

One example where this error shows up is in the `Dialog API`: in an `X11`
environment, the `zenity` driver requires access to the user's `DISPLAY` and
`XAUTHORITY` environment variables. Because these variables aren't transfered
to the `zenity` process, no dialogs are shown. This can be exercised in the
`test/testdialog.c` testprogram.

The fix changes the indirection level of the `dlsym` call from `char **` to
`char ***`, does a `NULL`-check in case the call failed, and returns the
dereferenced actual adress to the `environ` symbol.

(cherry picked from commit 10458f2cac)
2025-07-30 07:06:54 -07:00
Evan Hemsley
a65fbb0211 GPU: Fix incorrect block size when D3D12 uniform buffer is rotated (#13469)
(cherry picked from commit 07af4b237b)
2025-07-29 15:51:58 -07:00
Petar Popovic
46ec859bd1 Fix two use-after-free warnings
(cherry picked from commit f27dbb22f0)
2025-07-29 12:29:34 -07:00
Xen
2a7aa4eae4 Update SDL_clipboard.h
Typo fixes and a small addition to SDL_SetClipboardData about mime_type list usage clarity.

(cherry picked from commit b3ba1c159e)
2025-07-28 11:59:34 -07:00
Dan Andrus
c31ddf021e Check NSWindow::isVisible before sending SDL_WINDOWEVENT_RESTORED during Cocoa_WindowListener::windowDidResize
(cherry picked from commit 30f0aeb26a)
2025-07-28 14:47:45 -04:00
Shootfast
eaa2a8239f Fixed typo in SDL_scancode.h
The backslash/vertical line key is between the left shift and "Z" key on ISO keyboards

(cherry picked from commit 507ee033cc)
2025-07-27 19:58:45 -07:00
Brenton Bostick
d313ecb737 Fix warning on Android arm-v7
Building SDL for armeabi-v7a gives this warning:
```
SDL/src/audio/SDL_audiotypecvt.c:541:14: warning: '#pragma FENV_ACCESS' is not supported on this target - ignored [-Wignored-pragmas]
  541 | #pragma STDC FENV_ACCESS ON
```

(cherry picked from commit ed4de7aeed)
2025-07-27 08:16:21 -07:00
Petar Popovic
64b2af0340 SDL_gpu.c: Fixed deref-before-check warning
(cherry picked from commit 6a5af95364)
2025-07-26 12:08:57 -07:00
Anonymous Maarten
58d0702948 ci+n3ds: avoid apt-get package manager
- use Unix Makefiles (with parallelization) CMake generator
- use binutils strings binary from devkitpro

(cherry picked from commit e6d200e51c)
2025-07-26 16:06:36 +02:00
Sam Lantinga
707717e94b Reverted: Added Steam Virtual Gamepad support to the GameInput driver
This version of SDL doesn't support newer GameInput versions required for this feature.
2025-07-24 14:00:20 -07:00
Sam Lantinga
a140bba55a Fixed building with GameInput v1.0
(cherry picked from commit e5d57d8ad6)
2025-07-24 10:52:28 -07:00
Sam Lantinga
f4ddacacd0 Fixed building with GameInput v1.0
(cherry picked from commit 0ee0fe1572)
2025-07-24 10:43:05 -07:00
Sam Lantinga
ebba656bdb Added Steam Virtual Gamepad support to the GameInput driver
(cherry picked from commit 66dad9c21f)
2025-07-24 10:38:02 -07:00
Sam Lantinga
b78c61d67a Fixed double SDL_EVENT_GAMEPAD_ADDED for controllers with automatic gamepad mappings
(cherry picked from commit 6babade758)
2025-07-24 10:38:02 -07:00
L zard
4210aa61e1 build_config_windows: define HAVE_STDARG/STDDEF_H outside of
condition.
They are defined in both `#if HAVE_LIBC` and its `#else` anyway.
[sdl-ci-filter msvc-*]

(cherry picked from commit ea995b1694)
2025-07-21 14:45:19 -07:00
L zard
d8a345d924 build_config_windows: fix HAVE_VSSCANF defined regardless of MSVC version.
[sdl-ci-filter msvc-*]

(cherry picked from commit a977a11fa6)
2025-07-21 14:45:19 -07:00
Acclution
b8dc9767da GPU: Fix Vulkan compute uniform descriptor not being marked as set (#13389)
(cherry picked from commit 8bd29f7ca3)
2025-07-18 15:30:05 -07:00
BurntRanch
1ab01b9367 Clarify SDL_GPUVertexBufferDescription.pitch comment (#13381)
(cherry picked from commit ee6d8f78f4)
2025-07-17 08:55:04 -07:00
Sam Lantinga
ee371ff740 Fixed crash if a clipboard event was sent with video uninitialized
This can happen if you're using SDL on Android without using the video subsystem.

(cherry picked from commit 855d28e97a)
2025-07-17 08:48:00 -07:00
Evan Hemsley
ef58dd77ca GPU: Clean up properties in SDL_ReleaseGPUTexture (#13378) 2025-07-17 00:23:52 -07:00
Ryan C. Gordon
e6a7121904 audio: Binding an SDL_AudioStream will set missing formats.
It _must_ have the format set for the opposite side from the device (so
playback needs the src format set, and recording needs the dst format set),
since the stream gets mangled by the device thread if not. So if it has never
been set (stream created with NULL audiospec), just set it to match the device.
If the stream is just meant to buffer and not convert, this is desired
behavior, even if it didn't also fix a bug.

Binding the audio stream will always set the device side's format, as usual;
this does not need to be set by the caller at all.

Fixes #13363.

(cherry picked from commit f2ae6503c0)
2025-07-15 06:44:12 -04:00
Sam Lantinga
a6ed8ab59d Updated to version 3.2.19 for development 2025-07-14 11:44:22 -07:00
Sam Lantinga
bd40d0ded1 Removed the Mayflash GameCube adapter from the PS3 controller list
(cherry picked from commit 277f91c317)
2025-07-14 11:30:46 -07:00
Andon M. Coleman
68bfcb6c54 Allow 1 kHz sample rate for DualSense Edge over USB
DualSense Edge natively reports at 1 kHz for all connection types, but gyro sample rate was limited to 250 Hz for USB.

(cherry picked from commit a07cf3ecdc)
2025-07-14 10:02:46 -07:00
Josh Dowell
0d01efca52 windows: Fix crash when using a system that reports itself as Windows 17763 or newer, but is missing many of the newer dark mode window functions (Linux Mint Cinnamon w/ Proton 7.0.6)
(cherry picked from commit 0a50b798bf)
2025-07-13 20:10:26 -07:00
Kyle Sylvestre
0e65e04ce1 remove spoofed SDL_HelperWindow when SDL_VIDEO is off
(cherry picked from commit 0f061ff154)
2025-07-12 07:48:56 -07:00
Kyle Sylvestre
58d351fe98 check SDL_PLATFORM_WINDOWS instead of SDL_VIDEO_DRIVER_WINDOWS when using SDL_HelperWindow
(cherry picked from commit d42217ba26)
2025-07-12 07:48:56 -07:00
Kyle Sylvestre
9b71f18141 move SDL_HelperWindow outside of video
move to SDL_window.c to prevent relying on SDL_VIDEO

(cherry picked from commit a190e3b514)
2025-07-12 07:48:56 -07:00
Anonymous Maarten
554f08bac3 ci: build MSVC release binary on windows-2025 2025-07-12 01:25:08 +02:00
Sam Lantinga
913813a933 Updated to version 3.2.18 for release 2025-07-11 15:56:55 -07:00
Ryan C. Gordon
4e34c771e4 Revert "windows: Use wglSwapLayerBuffers if available."
This reverts commit b8ee44ca6a.

This is reverting a cherry-pick. It's probably too risky for a 3.2.x release,
but we'll let it marinate on main, for 3.4.0.
2025-07-11 18:25:14 -04:00
Ryan C. Gordon
9995174e68 gpu: Fixed uninitialized variable in SDL_AcquireGPUCommandBuffer().
Fixes #13191.

(cherry picked from commit 190afc0f4f)
2025-07-11 18:23:15 -04:00
Ryan C. Gordon
5a0197d430 wasapi: Force enumerated audio devices to report themselves as float32 format.
This is what they'll end up being when used through WASAPI in shared mode,
regardless of what the hardware actually expects.

Reference Issue #12914.

(cherry picked from commit a81cf566f4)
2025-07-11 18:23:01 -04:00
Sam Lantinga
4a55143e15 Fixed build
(cherry picked from commit 92e8224d32)
2025-07-11 14:12:27 -07:00
Sam Lantinga
87c9bc1b1f Fixed long delay when enumerating the Razer Huntsman keyboard
Fixes https://github.com/libsdl-org/SDL/issues/13236

(cherry picked from commit 0b2e389ee3)
2025-07-11 14:12:27 -07:00
Sam Lantinga
16a57b70f7 Set hwndTarget to NULL when unregistering raw input
Fixes https://github.com/libsdl-org/SDL/issues/13335

(cherry picked from commit 937e8d55a4)
2025-07-11 12:14:50 -07:00
Aleksey Sakovets
69564cd0b1 README-macos.md: replace old API calls
(cherry picked from commit 6386781351)
2025-07-11 12:08:58 -07:00
Ryan C. Gordon
da648b00e7 cocoa: Don't minimize fullscreen windows for a modal file dialog.
macOS sends a focus loss event when the dialog is created, which causes SDL
to try to minimize the window, which confuses the entire system. So in this
special case, don't do the minimization.

Fixes #13168.

(cherry picked from commit 9af93abd4f)
2025-07-11 15:06:10 -04:00
Sam Lantinga
5886d90308 Fixed long delay when enumerating the Razer Huntsman keyboard
Fixes https://github.com/libsdl-org/SDL/issues/13236

(cherry picked from commit f199aafaeb)
2025-07-11 11:56:06 -07:00
Ryan C. Gordon
e84df0cad1 x11: Avoid duplicate mouse events when using a pen device.
Fixes #12968.

(cherry picked from commit 72f4dd17be)
2025-07-11 14:31:07 -04:00
Frank Praznik
e482904111 Add support for non-constrained and non-grabbing popups
By default, popups are automatically constrained to be completely within display bounds, so as not to cut off information and result in an unusable menu, or unreadable tooltip. In some cases, however, this is not wanted, so a property to toggle this behavior is added.

There are also cases where the client may not want a popup menu to implicitly grab the keyboard focus, as is the default behavior, so popup menus now respect the focusable flag/property, as well as being able to toggle focus grabbing via SDL_SetWindowFocusable().

(cherry picked from commit b871ac0d97)
2025-07-11 14:26:51 -04:00
Ryan C. Gordon
b8ee44ca6a windows: Use wglSwapLayerBuffers if available.
It apparently works better (or can work better?) on multimonitor setups
than SwapBuffers.

This should be available back to Windows 95, but just in case, it falls
back to standard SwapBuffers if not available.

Fixes #13269.

(cherry picked from commit f286558bae)
2025-07-11 13:25:18 -04:00
Anonymous Maarten
4a4abe4240 cmake: remove /RTC1 from CXX flags when building with SDL_LIBC=OFF
(cherry picked from commit cfb8e591cb)
2025-07-11 10:00:22 -07:00
Wouter Wijsman
fe47f5cc30 PSP: Truncate thread name when passing to sceKernelCreateThread
(cherry picked from commit c64518f300)
2025-07-11 10:00:07 -07:00
Ryan C. Gordon
5b64be0810 docs: Documentation for SDL_Swap64 was reporting the wrong return type.
Fixes #13309.

(cherry picked from commit 530639aa4a)
2025-07-11 09:59:13 -07:00
Ryan C. Gordon
17656d051b cocoa: Don't use trick of briefly focusing the Dock on newer macOS releases.
On newer systems, the trick isn't necessary, and if you do it, if the user is
moving the mouse when launching the app, it'll show a hidden Dock.

Fixes #10340.

(cherry picked from commit 279dabfc96)
2025-07-10 15:54:25 -04:00
Ozkan Sezer
233fce456a fix ARM64 linkage with Visual Studio >= 17.14 when SDL_LIBC is disabled
Reference issue:  https://github.com/libsdl-org/SDL/issues/13254

(cherry picked from commit 2fb6abb9ad)
(cherry picked from commit fb0e03f262)
2025-07-09 01:32:00 +03:00
Frank Praznik
5290bb036c wayland: Ensure that the xdg_surface is always configured after creation
The spec states that xdg_surface must have seen an initial configure event before attaching a buffer, however, this was only being done when initially showing the window, and not after show->hide->show cycle.

Always wait for the initial configure event when (re)creating an xdg_surface as part of the show window sequence.

(cherry picked from commit ecdc6f2adb)
2025-07-05 12:10:28 -04:00
WillyJL
2bff72b4f6 SDL3 GPU: Fix -Wbool-conversion warnings
(cherry picked from commit 4eff36ef53)
2025-06-29 13:33:56 -04:00
Anonymous Maarten
08ebeaee5c cmake: Android always needs a native HIDAPI implementation
(cherry picked from commit 89eef1bd34)
2025-06-26 15:43:29 -07:00
Caleb Heuer
12b56f5447 Allow overriding SDL_FORK_MESSAGEBOX in build environment
(cherry picked from commit cd98b66114)
2025-06-26 10:49:48 -07:00
Frank Praznik
165b86e7b7 x11: Always update the borders on frame extent events
Always update the border sizes on frame extent events, or they can incorrectly still be zero if followed by a PropertyNotify event when leaving fullscreen.

Fixes sending the correct restored window size when leaving fullscreen in fvwm.

(cherry picked from commit 0ac1241b7a)
2025-06-26 11:53:32 -04:00
Sam Lantinga
608101a185 Update the viewport when logical presentation changes
Fixes https://github.com/libsdl-org/SDL/issues/13256

(cherry picked from commit 727b4924c8)
2025-06-25 09:59:13 -07:00
Paul Vick
554bee6aae Fix #13276: Crash in SDL_GetAudioDeviceChannelMap
(cherry picked from commit de6a23028a)
2025-06-25 09:59:07 -07:00
Rémi Verschelde
3e0ce51067 joystick: Fix MSVC errors C2099 with /fp:strict
(cherry picked from commit db3a35e9bc)
2025-06-24 07:32:26 -07:00
Ozkan Sezer
7261c43342 alsa: change an SDL_LogError into SDL_LogDebug.
it is informational only and seeing ERROR on the terminal was confusing

(cherry picked from commit af8bee2dd1)
2025-06-22 21:05:10 -07:00
Marcin Serwin
ad57c6ea37 test: Fix resource paths in testtray
Signed-off-by: Marcin Serwin <marcin@serwin.dev>
(cherry picked from commit bbc674b9e7)
2025-06-22 21:03:55 -07:00
mitchellcairns
caecff650d Resolve bug for calibration Nintendo Switch Pro Controller (#13260)
Resolves a bug which prevents the stored calibration data from loading, only allowing loading of factory-installed calibration data

(cherry picked from commit 796961acec)
2025-06-22 21:00:01 -07:00
Mitch Cairns
f6300be4b2 Fixed Nintendo Switch thumbstick calibration
(cherry picked from commit 3a6f9e01f8)
2025-06-22 15:27:30 -07:00
Sam Lantinga
bde5687a3c Fixed Nintendo Switch Pro thumbstick calibration
Fixes https://github.com/libsdl-org/SDL/issues/13246

(cherry picked from commit 038a3806eb)
2025-06-21 19:57:04 -07:00
Sam Lantinga
0f3504f78d Updated testffmpeg for ffmpeg 7.1
(cherry picked from commit e6c2649afc)
2025-06-21 08:49:43 -07:00
Sam Lantinga
0aaa0321cc Fixed warning C5286: implicit conversion from enum type 'VkFilter' to enum type 'SDL_ScaleMode' 2025-06-21 07:41:20 -07:00
Josh Dowell
caaaf52583 win32: Invalidate window message mouse button flags when reading buttons from raw input or GameInput
SDL2 would set a high bit in the mouse button flags to indicate when raw input had been read from, without this, if you hold down a mouse button and left raw input mode (leaving relative mode) the button would remain partially stuck, and would require two clicks to start producing mouse down events again.
SDL3's raw input code was refactored to not use the mouse button flags, but forgot to invalidate the flags, causing this bug to manifest.

(cherry picked from commit 6aedc488d3)
2025-06-21 07:29:05 -07:00
Ozkan Sezer
56449f167d hidapi/libusb: disable C5287 warning in MSVC builds
A quick search implies that it is a bogus warning:
https://www.google.com/search?q=visual+studio+C5287

(cherry picked from commit 81e3066303)
2025-06-21 07:16:36 -07:00
Ryan C. Gordon
c7325228dc audio: Enumerating audio devices will skip zombie devices still in the hash.
(cherry picked from commit eb04219efe)
2025-06-20 14:49:32 -07:00
Sam Lantinga
079967afa5 Clarify that SDL_GetAudioStreamDevice() returns the logical device.
(cherry picked from commit c19ad189dc)
2025-06-20 14:01:32 -07:00
Lilian Gimenez
2ed55b614c Fix support for F21 to F24 scancodes on Linux
(cherry picked from commit e4e29b8601)
2025-06-20 09:07:27 -07:00
Frank Praznik
28721e3cd2 test: Fix a window parenting bug in testmodal
(cherry picked from commit 390fe65323)
2025-06-18 09:27:03 -04:00
Frank Praznik
9d9845d063 video: Explicitly disallow setting the parent of a window to itself
Doing so causes a cycle in the window hierarchy tree graph, which leads to infinite recursion when destroying the windows.

(cherry picked from commit ca9b7c8ea3)
2025-06-18 09:27:03 -04:00
ceski
a96dc76831 Read Switch controller gyro/accel sensitivity coeffs (SDL3)
These vary by controller, so using the stored values should improve the accuracy of the sensor data.

(cherry picked from commit 558a89fdb6)
2025-06-13 12:18:43 -07:00
e4m2
ad8e517227 Tweak Vulkan include guard check and 64-bit platform defines (#13210)
(cherry picked from commit c5b1341757)
2025-06-12 09:32:32 -07:00
Sam Lantinga
8d578d590f Fixed replacing existing specific gamepad mappings
If the first mapping we see doesn't have a CRC, continue looking for another exact CRC match.

Fixes testautomation --filter TestVirtualJoystick

(cherry picked from commit 5826966873)
2025-06-06 09:55:04 -07:00
Sam Lantinga
6b4a211374 Added support for the ZEROPLUS P4 Wired Gamepad
(cherry picked from commit f90a21483c)
2025-06-06 09:27:17 -07:00
Sam Lantinga
55b023c961 Remove the CRC from automatically generated gamepad mappings
Fixes https://github.com/libsdl-org/SDL/issues/13127

(cherry picked from commit 638acdc02a)
2025-06-06 09:25:19 -07:00
Frank Praznik
e2d0fe3e2f x11: Resize fixed-size windows after mapping on xmonad
XMonad ignores size hints and shrinks the client area to overlay borders on fixed-size windows, even if no borders were requested, resulting in the window client area being smaller than requested. Calling XResizeWindow after mapping seems to fix it, even though resizing fixed-size windows in this manner doesn't work on any other window manager.

(cherry picked from commit 45eb6310a8)
2025-06-06 11:35:56 -04:00
Frank Praznik
6b56ff7a97 win32: Ensure that text input is initially disabled when creating a window
Windows seems to implicitly enable IME text input on windows created while an IME is active, which causes the IME suggestion window to pop up when keys are pressed, even if a client never explicitly enabled it. Ensure that IME support is initially disabled on new windows; SDL will enable it at a later time, if required.

(cherry picked from commit 22fa45b3c1)
2025-06-05 12:21:49 -04:00
Ethan Lee
67f796ebde gdk: Ignore focus loss events caused by text input showing the OSK 2025-06-04 09:41:06 -04:00
Sam Lantinga
06da7490fc Added support for the NACON Revolution X Unlimited controller on macOS
This adds support for the controller in Bluetooth mode.

Fixes https://github.com/libsdl-org/SDL/issues/13143

(cherry picked from commit 6622f4e1ea)
2025-06-03 15:08:11 -07:00
Sam Lantinga
af83c442d3 Fixed input from the MayFlash GameCube adapter with version 7 firmware
(cherry picked from commit 7457857304)
2025-06-03 11:14:09 -07:00
Sam Lantinga
d726e98596 Updated to version 3.2.17 for development 2025-06-02 15:57:36 -07:00
Caleb Cornett
c9a6709bd2 gpu: Add BC2_RGBA_UNORM_SRGB to GetBlockWidth/Height functions 2025-06-02 13:53:42 -07:00
Evan Hemsley
25816bea41 GPU: Binding validation and prevent null dereference if expected binding is missing (#13164) 2025-06-02 13:40:40 -07:00
Sam Lantinga
e0f6e96da0 Use HEAPU8.set rather than Module.HEAPU8.set (thanks @sbc100!)
The Module object is the external interface to the application, internal symbols like HEAPU8 don't need to be exported to be used and usage should not be prefixed with Module.

Fixes https://github.com/libsdl-org/SDL/issues/13156
Closes https://github.com/libsdl-org/SDL/pull/13157

(cherry picked from commit cf6c42e6e6)
2025-06-02 09:48:55 -07:00
Sam Lantinga
57de46ae7e Mark gamepads as invalid if they can't be opened
Fixes https://github.com/libsdl-org/SDL/issues/13129

(cherry picked from commit 4b0f48c4cf)
2025-06-02 09:25:10 -07:00
Sam Lantinga
59693c8996 Updated to version 3.2.16 for release 2025-06-01 14:37:23 -07:00
Ryan C. Gordon
f0efffc093 x11: Be a little less aggressive with Xinput2IsInitialized checks.
Just in case this ever get deinitialized sooner, we'd still like to SDL_free()
things on shutdown, etc.

Reference PR #13148.

(cherry picked from commit 9e0d9f30a7)
2025-06-01 10:15:54 -04:00
Mason Remaley
1b41cd759c Checks if xinput is loaded before trying to call xinput functions
(cherry picked from commit 57b6e6c7f9)
2025-06-01 10:15:47 -04:00
Ryan C. Gordon
d42a1402e8 audio: corrected comment about device format minimums.
(cherry picked from commit ac3ab026fe)
2025-06-01 03:01:47 -04:00
Ryan C. Gordon
5c44678d55 audio: Opened device spec must be >= simple minimums, not device's defaults.
Fixes #13159.

(cherry picked from commit 83cc3bc234)
2025-06-01 02:58:41 -04:00
Ryan C. Gordon
0638fd58ce pulseaudio: Request more recording data per-fragment.
This seems to help some devices that can't keep up with smaller fragment sizes
for whatever reason.

Fixes #13110.

(cherry picked from commit 14a4ae521a)
2025-06-01 02:48:49 -04:00
Ryan C. Gordon
cb662b6730 cocoa: add explicit tracking areas to the window.
This makes sure we get reliable mouse enter/exit events from the system on
older macOS releases.

Newer releases don't have this problem--my assumption is that Cocoa has a
more aggressive default tracking area installed for some newer UI feature.

For 3.2.16, we'll use the explicit tracking area on older macOSes only, but
I'll remove that check in revision control for newer OSes and see what
happens.

Fixes #12725.

(cherry picked from commit f61d956a04)
2025-05-31 14:45:43 -04:00
Caleb Heuer
e874c7515e Pass text input rect to steam deck keyboard invocation
(cherry picked from commit 51dfca813b)
2025-05-30 09:54:53 -07:00
Ethan Lee
2ba797576b storage: Declare a private bootstrap for NDA user storage 2025-05-30 12:15:43 -04:00
Sam Lantinga
180b454d61 kmsdrm: fixed creating GBM surfaces on NVIDIA cards
(cherry picked from commit fc1c0618de)
2025-05-29 11:20:44 -07:00
DracoRooks
6ce7ae77b1 Update SDL_pixels.h
Added an opening bracket in line 520, in the comment block of SDL_PixelFormat. Simple addition to the readability of documentation.

(cherry picked from commit 03a6d98aee)
2025-05-29 11:03:54 -07:00
Sam Lantinga
abbaf95cf0 Added macros to push/pop error messages while cleaning up
(cherry picked from commit 885e611f3c)
2025-05-29 10:54:46 -07:00
Sam Lantinga
1081b70951 Fixed typos
(cherry picked from commit 61d105247e)
2025-05-29 10:54:46 -07:00
Sam Lantinga
4f51f956ad Updated SDL_StretchSurface() documentation
Fixes https://github.com/libsdl-org/SDL/issues/13135

(cherry picked from commit 7db0ac7380)
2025-05-29 09:09:29 -07:00
Sam Lantinga
b076f4b590 Removed obsolete documentation
(cherry picked from commit 737b9e117d)
2025-05-28 15:57:23 -07:00
Sam Lantinga
91180f8cb4 Disable SDL_HINT_JOYSTICK_RAWINPUT by default
Windows can get in a state when it stops reporting raw input events for game controllers until reboot.

The downside of this change is that we lose support for trigger rumble and are limited to 4 controllers again, but if that's important for your application you can use SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, true) to enable this functionality.

Fixes https://github.com/libsdl-org/SDL/issues/13047

(cherry picked from commit aa870d511e)
2025-05-27 09:51:58 -07:00
Ethan Lee
99aa859362 gpu: Xbox buildfix 2025-05-27 12:42:46 -04:00
Frank Praznik
31267feb03 wayland: Use raw timestamps to calculate the elapsed repeat time on a key up event
Using processed timestamps can result in anomalies that cause excessive repeat events, and hard caps can cause issues.

In the key event handler, use the raw elapsed time to calculate any remaining repeat events to avoid the artifacts that can result from using processed timestamps.

The Wayland key repeat rate ranges from 0 to 1000 per second, so millisecond resolution doesn't lose any precision.

(cherry picked from commit e3d44cdd51)
2025-05-27 11:18:56 -04:00
Sander Ledegen
6a5bac72cb PSP fullscreen is the only mode (#13125)
(cherry picked from commit 9b025e3cab)
2025-05-26 10:32:13 -07:00
Ozkan Sezer
2ed5062950 SDL_video.c: remove two stray line continuation chars .
(cherry picked from commit 25db127450)
2025-05-26 01:45:50 +03:00
Christian Kündig
0b0b02c5a1 emscripten: Proxy Emscripten_GetSystemTheme and EMSCRIPTENAUDIO_OpenDevice to the main thread.
(cherry picked from commit 168d1a9253)
2025-05-25 13:50:19 -07:00
mattbsage
28c71368a1 Clean up INTERFACE_COMPILE_OPTIONS
The extra text causes Meson/Ninja builds to fail as headers are not found.

(cherry picked from commit f62572344f)
2025-05-24 19:13:41 -07:00
Frank Praznik
25bd4285ab x11: Assume the window was mapped after showing
Not all window managers send a MapNotify or PropertyNotify event when the window is shown, so assume that it was mapped and set the flag accordingly.

(cherry picked from commit b70919ecd9)
2025-05-24 10:00:43 -04:00
Frank Praznik
180171cad6 x11: Always send fullscreen dimensions except on XWayland
More non-compositing window managers than just openbox seem to need this, so always force sending the window position and dimensions when entering/leaving fullscreen. If they are wrong, they will be immediately overwritten by the correct dimensions from a subsequent ConfigureNotify event.

This is disabled on XWayland, as it seems to cause hitching on some compositors.

(cherry picked from commit 0657ece55d)
2025-05-24 10:00:43 -04:00
Sam Lantinga
bc3eeecf7f Set the initial axis values for HIDAPI and XInput controllers
Fixes https://github.com/libsdl-org/SDL/issues/13020

(cherry picked from commit 1f6b5c681d)
2025-05-23 12:09:58 -07:00
Frank Praznik
9178d14519 x11: Include the XTest header when needed
Fixes building when statically linking.

(cherry picked from commit fdc4f8fa39)
2025-05-23 13:12:47 -04:00
Ivan Epifanov
6cd35f5b72 VITA: support only fullscreen windows. Fixes #13079
(cherry picked from commit 2b4d61e4a6)
2025-05-23 08:45:49 -07:00
kyle-sylvestre
72d5eb0ecb fix error handling in WideCharToMultiByte
(cherry picked from commit ead32c706d)
2025-05-22 15:25:58 -07:00
kyle-sylvestre
5cf924420d bugfix advancing UTF-8 length in UTF-16 string
(cherry picked from commit 8ddb074889)
2025-05-22 15:25:58 -07:00
Ryan C. Gordon
290574e6f6 stdinc: Corrected documentation for SDL_atan2 and SDL_atan2f.
Fixes #13099.

(cherry picked from commit 8d9a4fe843)
2025-05-22 09:52:51 -04:00
Frank Praznik
d9db975b4b wayland: Use SDL_memcpy instead of SDL_copyp to copy the repeated text string
SDL_copyp is not intended to copy arrays. Use SDL_memcpy with the explicit size instead.

(cherry picked from commit abcfa1b7de)
2025-05-21 20:39:03 -04:00
Matteo Hausner
e5c0e5efa7 Fix #13083 segfault in SDL_RemoveTrayEntry() for submenu entries
Use `g_object_ref_sink()` in `SDL_CreateTraySubmenu()` as introduced with
3be67ced64 for the top-level menu.

(cherry picked from commit 22828d5f2a)
2025-05-21 13:32:47 -07:00
Sam Lantinga
26a1aae098 Fixed the Bluetooth flag for the combined Joy-Con controller
(cherry picked from commit 264eb8d440)
2025-05-21 13:30:30 -07:00
Frank Praznik
ab114490fc wayland: Cap the max key repeat elapsed time
Cap the elapsed time to something sane in case the compositor sends a bad timestamp, which can result it in it looking like the key has been pressed for a *very* long time, bringing everything to a halt while it tries to enqueue all the repeat events.

(cherry picked from commit 05f779f61e)
2025-05-21 12:20:31 -04:00
kyle-sylvestre
9546c54286 use SDL style - else on same line as closing brace
(cherry picked from commit b8e055ce64)
2025-05-20 17:13:47 -07:00
kyle-sylvestre
4d3cdb70b5 get preferred locales on android
(cherry picked from commit 8e22194217)
2025-05-20 17:13:47 -07:00
Anthony Fisher
a66816a72f gpu/d3d12: Acknowledge that we've bound vertex buffers (#13088) 2025-05-20 16:34:27 -04:00
Francisco Javier Trujillo Mata
c925f72562 Fix wrong callback type
(cherry picked from commit c89357bf60)
2025-05-20 11:11:01 -07:00
Logan
ef97329f41 GPU: Update D3D12 to create multisample textures with default MSAA alignment
(cherry picked from commit f4942b3eae)
2025-05-20 11:07:54 -07:00
Frank Praznik
195f709eda wayland: Set the text input cursor rect properly
The text input cursor should reflect the cursor position, not the entire text input rect. Set it correctly so that IME chooser dialogs appear in the correct location.

(cherry-picked from commit c7549eb0b6)
2025-05-20 13:42:21 -04:00
cosmonaut
eb57d94ec5 GPU: Add missing compute-writeable texture formats 2025-05-19 18:11:06 -07:00
Sam Lantinga
d6212ae839 Fixed rare crash trying to interrupt SDL_WaitEvent()
Fixes https://github.com/libsdl-org/SDL/issues/12797

(cherry picked from commit 992e4c59bd)
2025-05-19 14:16:25 -07:00
Frank Praznik
b494897b3d wayland: Don't add the nanosecond timestamp offset to the pre-conversion millisecond value
(cherry picked from commit 6c61a94a4b)
2025-05-19 14:00:12 -04:00
Sam Lantinga
559d4415eb Fixed touch not being delivered as mouse events by default on Vita
Closes https://github.com/libsdl-org/SDL/pull/13070

(cherry picked from commit 25f2376e79)
2025-05-19 08:33:28 -07:00
Joe [ReRezd]
49e9134774 Fix: GameCube controller adapter hotplug not working
SDL_PrivateJoystickAdded was called before setting the InstanceId in the adapters ctx->joysticks array.  This would eventually broadcast the SDL_EVENT_JOYSTICK_ADDED event with the new InstanceId, if your program listens for the added events and opens joysticks at that point it would always fail because there would be no matching InstanceId in the ctx->joysticks array.

(cherry picked from commit afd1e51023)
2025-05-19 08:25:16 -07:00
Logan
9571b0ece8 GPU: Update to set supported shader formats inside CreateDevice
(cherry picked from commit 8289656a4e)
2025-05-18 18:33:07 -07:00
danginsburg
b55cfaf90b Fix #13057 - fixes bug with NSEventTypeMouseMoved having a NULL window causing us to suppress future mouse move events because the window was considered out of focus.
(cherry picked from commit 968222e74f)
2025-05-16 17:07:49 -07:00
ScolderCreations
509168856f Fix reference to nonexistent "README-3ds.md"
(cherry picked from commit d16371b923)
2025-05-15 11:23:17 -07:00
Stéphane GINIER
24fa2722c3 MacOS: fix cocoa clipboard text
Adjust Cocoa_SetClipboardData so that SetClipboardText text can be pasted outside SDL

(cherry picked from commit 945eb6dc87)
2025-05-15 10:54:15 -07:00
Evan Hemsley
142700f909 GPU: Check that a texture format is valid for compute writes (#13044) 2025-05-14 16:25:24 -07:00
Evan Hemsley
f3611681df GPU: Always return NULL if beginning a pass fails an assert check 2025-05-14 15:23:57 -07:00
Sam Lantinga
7f0a5d6a10 Updated to version 3.2.15 for development 2025-05-14 13:08:44 -07:00
cosmonaut
2001cc15d5 GPU: Debug mode layer and level index checks 2025-05-14 12:25:18 -07:00
Frank Praznik
8d604353a5 renderer: Always use the output size when updating the main view
The main view always reflects the size of the output, so don't use the dimensions of the currently bound render target texture when updating it, or it will reflect an incorrect size when the render target texture is unbound.

(cherry picked from commit 8aa5b97bb5)
2025-05-14 09:38:13 -07:00
Ryan C. Gordon
8410e11ecb wikiheaders: Man pages should escape apostrophe chars.
This prevents problems if one starts a line, which would cause it to be
interpreted as a command character.

Fixes #13038.

(cherry picked from commit 1f7aa16eae)
2025-05-14 11:41:14 -04:00
krizej
9f8161bf4a docs: improve man page generation
(cherry picked from commit a390f5716e)
2025-05-14 11:40:58 -04:00
Sam Lantinga
c038d6f7f8 Updated to version 3.2.14 for release 2025-05-13 14:24:40 -07:00
Frank Praznik
2fff37fffc Revert "x11: Send key events for dead keys consumed by the IME"
This and its related commits introduced some bugs and quirks such as duplicated and delayed/missed key events that can't be easily worked around, so revert this for now.

This reverts commit 47162a4168.

(cherry picked from commit 1eeffc5933)
2025-05-13 09:22:13 -07:00
Frank Praznik
6feb86be71 Revert "x11: Filter out duplicate key presses when an IME is active"
This reverts commit f4813ca2cf.

(cherry picked from commit 3304d24bea)
2025-05-13 09:22:13 -07:00
Sam Lantinga
ed22220bc6 Fixed crash if out of memory in the Vulkan GPU driver
(cherry picked from commit cd95152b2c)
2025-05-13 09:08:19 -07:00
Andrey Moura
219cb1a59d joystick: Fix linker error when building without virtual joystick support
SDL_VIRTUAL_JoystickDriver was referenced outside an #ifdef when setting is_virtual, which caused a linker error. I modified it so that is_virtual is set to false if virtual joystick support is not enabled.
2025-05-13 08:55:29 -07:00
Simon McVittie
71bd25a893 audio: Assert that all devices from device_hash are the appropriate type
The keys and values of device_hash are pairs
`(SDL_AudioDeviceID devid, void *dev)` where dev can be either a
`SDL_AudioDevice *` or a `SDL_LogicalAudioDevice *`, depending on
bit 1 of devid.

We can confirm that we have got this right by looking at the
instance_id member, because logical audio devices happen to start with
the devid, whereas physical devices start with a pointer which is
unlikely to match the devid by chance.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 70b2d162e3)
2025-05-13 08:53:35 -07:00
Ryan C. Gordon
01ef4c46a1 audio: Fix SDL_GetAudioDeviceName() not working with logical devices.
Fixes #12977.

(cherry picked from commit 0a34279578)
2025-05-12 13:54:52 -04:00
yunline
64f728ec48 tray: Fix wrong fByPositon parameter of SetMenuItemInfoW in SDL_SetTrayEntryLabel
(cherry picked from commit 9a6f70d75a)
2025-05-12 08:40:44 -07:00
Mike Kosek
ba10adf1fb Added rightx and righty
(cherry picked from commit 38da39c8c9)
2025-05-12 08:40:44 -07:00
Dominic Bolin
c18aa99358 GPU Vulkan: set correct destination usage mode for storage buffer read/write bindings (#13009) 2025-05-11 16:12:37 -07:00
ManuBlack
3498412611 AAudio: Implemented sample frames hint
(cherry picked from commit c6e9d6cc79)
2025-05-11 16:06:13 -07:00
Ryan C. Gordon
8c1b3ff210 Revert "pulseaudio: cleanup TLS every time we finish a threaded-mainloop callback."
This reverts commit 3b91017682.

This apparently is cleaning up more threads than expected, so this needs a
rethink.

Fixes #12986.
Fixes https://github.com/libsdl-org/sdl2-compat/issues/486
Fixes https://github.com/libsdl-org/sdl2-compat/issues/482

(cherry picked from commit e1066ceea1)
2025-05-11 10:23:04 -07:00
Frank Praznik
1870052af6 x11: Fix the Openbox quirk flag
Openbox needs fullscreen size/position event synthesized, but does not send display changed events.

(cherry picked from commit 84308e7fba)
2025-05-10 15:50:48 -04:00
dbolin
3b1e3d5176 GPU Vulkan: fix for Swapchain Semaphore Reuse
(cherry picked from commit 6344712b04)
2025-05-10 07:56:07 -07:00
RipleyTom
cdf26c6e97 Add hid_version and hid_version_str to renamed LIBUSB impl symbols
(cherry picked from commit e90f7ac4a8)
2025-05-10 07:45:37 -07:00
Evan Hemsley
9f1a1405a6 GPU: Special case to avoid assert on GenerateMipmaps (#12995)
(cherry picked from commit 86b206dadf)
2025-05-09 22:00:57 -07:00
Sam Lantinga
6e97d8d1b3 Fixed crash if WGI isn't correlated in RAWINPUT_JoystickRumble()
(cherry picked from commit 87fe9ef79b)
2025-05-08 15:39:50 -07:00
Sam Lantinga
9d9a24d325 Define illegal_instruction() when it will be actually used
(cherry picked from commit 29d2116495)
2025-05-08 12:50:08 -07:00
Sam Lantinga
0897f4a7d1 Backported Metal sampler improvements from main
Fixes https://github.com/libsdl-org/SDL/issues/12988
2025-05-08 10:22:17 -07:00
Sam Lantinga
5aec645191 Added GCController mapping for the 8BitDo SN30 Pro on macOS
(cherry picked from commit 2b57d58f7d)
2025-05-08 09:57:36 -07:00
Sam Lantinga
07c33068f3 Added GCController mapping for the 8BitDo Pro 2 on macOS
Fixes https://github.com/libsdl-org/SDL/issues/12987

(cherry picked from commit d157600d3d)
2025-05-08 09:49:46 -07:00
expikr
d684e5d57e fix #12963
(cherry picked from commit 6b048f59d7)
2025-05-06 21:18:02 -07:00
Frank Praznik
219500d95c x11: Filter out duplicate key presses when an IME is active
IME text events can result in sending duplicate key press events, which will result in undesired repeated key presses. Since the events are exact duplicates, compare the serials to filter out redundant key down events.

(cherry picked from commit f4813ca2cf)
2025-05-06 18:21:39 -04:00
Frank Praznik
810addf7ae x11: Don't update grab on enter when the mouse is captured
The xserver will still send EnterNotify events while the pointer is captured, and the grab shouldn't be updated in these cases, as it will cause the capture to be lost.

(cherry picked from commit 33e5f4885a)
2025-05-06 14:50:16 -07:00
Frank Praznik
4ef077ca52 Revert "x11: Better handle XInput2 mouse tracking outside the window"
This reverts commit 8c733d1f7b.

(cherry picked from commit 1abac3ccc3)
2025-05-06 14:50:16 -07:00
Sam Clegg
7d2275c4dc [emscripten] Remove referenc to Module['createContext']
The Module interface is the one used by the outside world.  This code
is inside the module itself so can use the internal name, avoiding the
need to export this function on the Module at all.

See https://github.com/emscripten-core/emscripten/pull/24269

(cherry picked from commit 8e1f4bafb4)
2025-05-06 14:16:36 -07:00
Ivan Epifanov
cbd8917047 VITA: fix audio playback
(cherry picked from commit 1dbb813316)
2025-05-06 12:55:34 -07:00
Frank Praznik
c98a19401c x11: #ifdef the XRandR path in the message box code
The runtime check isn't sufficient as the functions are undefined if built without XRandR.

(cherry picked from commit c91f9f6968)
2025-05-05 11:16:03 -04:00
A. Wilcox
434836c480 cpuinfo: Use auxv for AltiVec on Linux if possible
The SIGILL handler is not very reliable and can cause crashes.

Linux provides the CPU's AltiVec support status in getauxval.

(cherry picked from commit 7490471796)
2025-05-04 13:53:10 -07:00
Sam Lantinga
50d02ad732 Updated to version 3.2.13 for development 2025-05-04 10:56:10 -07:00
Ozkan Sezer
5ac37a8ffc don't prototype strdup() for __clang_analyzer__ case in windows builds.
Fixes:  https://github.com/libsdl-org/SDL/issues/12948.
(cherry picked from commit 17bba029ba)
2025-05-04 10:36:33 -07:00
Sam Lantinga
7dd2915475 Updated to version 3.2.12 for release 2025-05-04 10:09:23 -07:00
Frank Praznik
0ae1ddee17 win32: Hide the borders when showing a fullscreen window
If it is known that the window will immediately enter fullscreen upon being shown, set the borderless style when showing the window to hide the borders, or they may linger in the background if the client takes some time to draw the first frame.

Unnecessarily calling ShowWindow with SW_RESTORE when applying the window flags must be suppressed in this case, or the borders can reappear in a weird, partial state.

(cherry picked from commit d73fe0bc53)
2025-05-02 14:22:14 -04:00
Sam Lantinga
db4c7e47f1 Added support for the share button on the GameSir-K1 FLUX controller
(cherry picked from commit ab12b7cbba)
2025-05-02 10:15:39 -07:00
Sam Lantinga
362445460e Added support for the PowerA Battle Dragon Advanced Wireless Controller
(cherry picked from commit 1e6a25324c)
2025-05-02 10:01:42 -07:00
Ryan C. Gordon
de5cb9db23 dialog: Cocoa backend should reactivate the app after the modal dialog.
Otherwise the window won't have focus until you click on it again. Calling
makeKeyAndOrderFront isn't enough to fix it, either.

This trick comes from a similar problem we solve in our
applicationDidFinishLaunching implementation: activate (give app focus to) the
system Dock, as something that definitely exists that isn't us and is harmless
to activate, and then activate us right afterwards. This unconfuses whatever
is getting confused inside Cocoa.

Fixes #12684.

(cherry picked from commit 57346f2ba8)
2025-05-02 01:54:56 -04:00
Ryan C. Gordon
418eab29eb uikit: Use SDL_RunOnMainThread instead of dispatch_sync for message boxes.
Reference Issue #12741.

(cherry picked from commit 193b0c8963)
2025-05-02 01:54:17 -04:00
Ryan C. Gordon
2f3d242183 dialog: Cocoa shouldn't crash if there's a '.' in the filters.
So something like "index.pb" will now accept any file with a ".pb" extension,
to make macOS happy. This seems like a reasonable tradeoff.

Other minor cleanups.

Fixes #12778.

(cherry picked from commit 691cc5bb5e)
2025-05-01 21:37:54 -07:00
Cameron Gutman
4ad6d18203 events: Add integer wheel fields for sdl2-compat
It's way simpler to just add them back to SDL3 than emulate them purely in sdl2-compat.

(cherry picked from commit 0447c2f3c3)
2025-05-01 22:51:54 -05:00
Temdog007
cd4a4f8a9f X11: Center Message Box on Multi Monitor Displays (#12819)
Use XRandr to find the position of the current screen to center the message box on that window

(cherry picked from commit 4ef8b6ce1b)
2025-05-01 13:39:26 -07:00
Frank Praznik
a96e72da02 video: Store the preferred fullscreen display in a property for sdl2-compat
sdl2-compat will call SDL_GetDisplayForWindow() when querying the display to use for fullscreen, which won't always be correct if the backend can't actually reposition the window. When calling this function, get the ideal fullscreen display and store it in a property for retrieval by sdl2-compat.

(cherry picked from commit c5d5967c3a)
2025-05-01 11:25:03 -07:00
Sam Lantinga
337f012de2 Fixed right mouse button emulation when using a pen
Pen button 1 is typically used as right click. Pen button 2 (Wacom eraser) doesn't have a specific mapping, but we'll use middle click for now.

(cherry picked from commit e3df61b070)
2025-04-30 11:08:24 -07:00
Sam Lantinga
3c29b620e4 Fixed missing simulated mouse events using a Wacom tablet
The low 16-bits of the message extra info is an event sequence number when using the Wacom tablet with Windows Ink disabled. The high bits of normal mouse motion when using touch input match the touch signature, 0xFF515700. The high bits of raw input mouse motion when using touch input do not match that signature, so we have to check for the touch bit in that case.

Fixes https://github.com/libsdl-org/SDL/issues/12927

(cherry picked from commit 106ccc722e)
2025-04-30 11:08:24 -07:00
Sam Lantinga
579fc161f0 Fixed build
(cherry picked from commit 8ae962c904)
2025-04-29 19:57:15 -07:00
Sam Lantinga
22e968af4e Fixed right click mouse emulation for the Wacom tablet
The problems are two-fold. When this happens a WM_POINTERDOWN event is sent with IS_POINTER_INCONTACT_WPARAM() evaluating as true. So when SDL_SendPenButton() is sent for the barrel button, there is no pen in contact yet, so the right mouse button is sent. Then SDL_SendPenTouch() is sent, which generates a left button press event.

Fixes https://github.com/libsdl-org/SDL/issues/12926

(cherry picked from commit e04064350f)
2025-04-29 19:57:15 -07:00
Ryan C. Gordon
e37e96cfff pen: Windows can't check WM_POINTER[DOWN|UP] for touches directly.
These events fire for other things, such as pressing a barrel button while
the pen is hovering.

The correct thing to do is check IS_POINTER_INCONTACT_WPARAM in the event.

If the pen is already touching or not, SDL_SendPenTouch() will do the right
thing, so it's safe to call it even if we're already in the right state.

(cherry picked from commit ea67133e4f)
2025-04-29 19:57:15 -07:00
Evan Hemsley
56c76c20a0 GPU: Validate that textures are not bound for both read and write on render passes (#12925)
(cherry picked from commit a163257295)
2025-04-29 16:53:45 -07:00
Evan Hemsley
efd812c399 GPU Vulkan: Add locks for layout object lookups (#12924)
(cherry picked from commit e1a41c1c97)
2025-04-29 15:44:37 -07:00
Sam Lantinga
b2b92bbe25 Removed timeout in SDL_RunOnMainThread()
Fixes https://github.com/libsdl-org/SDL/issues/12923

(cherry picked from commit 8abcc27535)
2025-04-29 08:58:54 -07:00
Sam Lantinga
a29c67ac94 Always enable D3D12 GPU on Windows
This isn't dependent on the render subsystem

Fixes https://github.com/libsdl-org/SDL/issues/12922

(cherry picked from commit ef54c3bf18)
2025-04-29 08:53:40 -07:00
Cameron Gutman
f88e0aaac0 events: Fix undefined behavior when disabling some event types
Shifting a signed int left by 31 is UB.

(cherry picked from commit 39d3148185)
2025-04-29 00:27:02 -05:00
Ozkan Sezer
29a4a4a5d1 tray, unix: make pointers g_object_ref and g_object_ref_sink static
Fixes:  https://github.com/libsdl-org/SDL/issues/12908.
(cherry picked from commit 016ba86f93)
2025-04-27 10:22:18 -07:00
Frank Praznik
01000c73b0 cocoa: Immediately update the mouse focus when showing/hiding a popup menu
When showing or hiding a popup menu, manually check and set the focus if the new topmost window under the cursor is an SDL window. Otherwise, the focus won't be updated until the cursor is actually moved.

(cherry picked from commit 6f5892e543)
2025-04-27 09:39:36 -04:00
Frank Praznik
1a5d1dfef0 x11: Better handle XInput2 mouse tracking outside the window
There is a quirk with XInput2 mouse capture that causes a leave event to be sent if the pointer moves out->in->out, which breaks mouse tracking outside the window. If the mouse leaves the window with buttons pressed, continue tracking it until the buttons are released.

(cherry picked from commit 8c733d1f7b)
2025-04-26 13:16:19 -04:00
Austin Almond
2c38143834 GDK: Handle ProjectDir with space
The call to compile_shaders_xbox.bat fails if ProjectDir contains a space. Wrapping the command in quotes fixes the issue.

(cherry picked from commit 14ae45c2b8)
2025-04-25 15:01:07 -07:00
Ryan C. Gordon
c56a1c664c aaudio: We PlayDevice first and WaitDevice after; reduce semaphore count by 1.
Previously, we would WaitDevice first, but that would feed a silent buffer
to AAudio upfront, introducing latency. When this change was made, the
semaphore count should have been adjusted, since we're waiting on one less
buffer.

Fixes #12882.

(cherry picked from commit 2767c1a440)
2025-04-25 15:08:56 -04:00
Ryan C. Gordon
41cae64580 pipewire: Use a more specific stream name than "Audio Stream".
This info shows up in `pw-top` ...Gnome's sound preferences (etc) would
already show something more app-specific, but this command line tool shows
specific stream names.

(cherry picked from commit a9bee3c0bf)
2025-04-25 14:26:03 -04:00
Ryan C. Gordon
c6dd2662c3 pulseaudio: cleanup TLS every time we finish a threaded-mainloop callback.
These callbacks run in a thread we don't control, but might call SDL_SetError,
which will claim a TLS slot that never gets otherwise deallocated. To prevent
the leak, finish each callback by explicitly freeing any thread-local data.

Fixes #12732.

(cherry picked from commit 3b91017682)
2025-04-25 14:25:51 -04:00
Ryan C. Gordon
f48027cf12 audio: Tweak SDL_GetAudioDeviceName.
- Add checks that ObtainPhysicalAudioDevice() was previously doing
  (is subsystem initialized, is device valid).
- Remove optimizations that copy string to stack to release device_hash_lock
  before SDL_GetPersistentString is called. Probably not necessary, and made
  the code more complex.

(cherry picked from commit b28449a58c)
2025-04-25 08:12:52 -07:00
Anonymous Maarten
fabbc8d183 cmake: use CMAKE_ANDROID_NDK variable as root of Android ndk
This variable is always defined when targeting Android:
- when using the toolchain file shipped along the ndk
  (using  -DCMAKE_TOOLCHAIN_FILE=$ENV{ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake)
- when using the toolchain file provided by CMake
  (using -DCMAKE_SYSTEM_NAME=Android)

(cherry picked from commit 5b1e92ae88)
2025-04-25 07:59:05 -07:00
Frank Praznik
a142e5ef7d cocoa: Popup menus always accept first click
(cherry picked from commit 09b2aae47e)
2025-04-25 09:36:12 -04:00
Sam Lantinga
825c0c7691 Reset the keyboard when entering a modal loop on Windows
Fixes https://github.com/libsdl-org/SDL/issues/12876

(cherry picked from commit da3c864d4c)
2025-04-24 13:58:56 -07:00
expikr
dc30a00a26 use GetMessagePos instead of GetCursorPos
(cherry picked from commit a82f70dc21)
2025-04-24 13:27:42 -07:00
kiddkaffeine
5a05ef01ad Fix crash in UIKit indirect pointer handling
(cherry picked from commit 5cacdf2513)
2025-04-24 13:05:23 -07:00
Alynne
0237997e4d Add Padix Rockfire devices (#12884)
(cherry picked from commit 32bbabe2a5)
2025-04-24 11:28:48 -07:00
Robert Müller
4f90432a49 Emscripten: fix incorrect error check for WebGL context creation
According to the documentation and testing the `emscripten_webgl_create_context` function returns `0` on error as oppposed to a negative number. This was causing the error message to be empty when the later `emscripten_webgl_make_context_current` call fails given the invalid context.

See https://emscripten.org/docs/api_reference/html5.h.html#c.emscripten_webgl_create_context

(cherry picked from commit 7e1d4f843c)
2025-04-24 11:26:16 -07:00
expikr
0cd6942bfc defer clipcursor refresh unto pump finish
(cherry picked from commit dd625a6763)
2025-04-24 10:37:30 -07:00
expikr
1beb6fdedf pass ground-truth cursor pos to WIN_UpdateFocus
(cherry picked from commit c84c2aa2c4)
2025-04-24 10:37:30 -07:00
Frank Praznik
3b4472ecf7 x11: Handle size/position events arriving before state events
Xfce, unlike every other window manager in existence, sends ConfigureNotify events before PropertyNotify events when toggling the fullscreen and maximized window state. Check the window state when handling ConfigureNotify events, and defer emitting SDL size/position events until the corresponding PropertyNotify event arrives, since SDL and clients expect to get the window state before the new size and position.

(cherry picked from commit 11a3296a42)
2025-04-24 12:29:24 -04:00
Frank Praznik
faed8b620c audio: Fix warning C4701: potentially uninitialized local variable 'isstack' used
This warning is actually wrong, as the variable is only used if the string pointer is valid, in which case it was initialized, but this is needed to quiet MSVC.

(cherry picked from commit fb940fff80)
2025-04-24 08:49:48 -07:00
Ryan C. Gordon
982b778e45 audio: SDL_GetAudioDeviceName() doesn't need a full device lock.
Fixes https://github.com/libsdl-org/sdl2-compat/issues/468

(cherry picked from commit e8bd9cc150)
2025-04-24 08:49:48 -07:00
Vicki Pfau
3a8f1cb7c5 Joystick: Add trigger rumble resend
This was already present for regular rumble to ensure that controllers would
continue rumbling for extended periods, but was missing for trigger rumble. I
don't know if this affects any controllers at the moment, but it's helpful for
future-proofing.

(cherry picked from commit ceb9fecfc1)
2025-04-24 08:48:19 -07:00
Logan Benjamin
3c2d7ecdd6 GPU D3D12 - Update to use typeless formats for depth buffer (#12701)
For a depth buffer in D3D12 that is also going to be used in a texture sampler, the creation (on an Intel HD 5500 igpu) fails. e.g. SDL_GPUTextureCreateInfo type = TEXTURE_2D, format = D32_FLOAT, usage = DEPTH_STENCIL_TARGET | SAMPLER

The error messages are:

D32_FLOAT
D3D12 ERROR: ID3D12Device::CreateShaderResourceView: The Format (0x29, R32_FLOAT) is invalid when creating a View; the
Resource was already created with a fully qualified Format, which is not castable (0x28, D32_FLOAT).

D24_UNORM
D3D12 ERROR: ID3D12Device::CreateShaderResourceView: For the resource format D24_UNORM_S8_UINT, when making a D3D view, the format name for the view can't be R24_UNORM_X8_TYPELESS.

I found this is because the texture format needs to be created as _TYPELESS, then the views (depth stencil view, shader resource view) should then be created as their respective types - e.g. texture = R32_TYPELESS, dsv = D32_FLOAT, srv = R32_FLOAT

Tested and working on:
NVidia RTX 3050 (D3D12 feature set 12_2)
Intel HD 5500 (D3D12 feature set 11_1)

(cherry picked from commit c81b62293a)
2025-04-23 16:30:47 -07:00
Petar Popovic
0834f1d6ce SDL_GetRectIntersectionFloat(): Allow rendering zero-sized srcrect
(cherry picked from commit 27b256022b)
2025-04-23 16:16:24 -07:00
Lucas Murray
6ce446b768 GPU: Make D3D12 debug layers optional
(cherry picked from commit d04b28926c)
2025-04-23 16:16:24 -07:00
Sam Lantinga
e045edb567 Corrected documentation for SDL_SetGPUSwapchainParameters()
(cherry picked from commit 695cad459b)
2025-04-23 16:16:24 -07:00
Ozkan Sezer
6cd14660cf stb_image.h: apply mainstream PR/1736
Fix root-cause of CVE-2021-45340 : dereference of NULL ptr.
Patch authored by Henner Zeller <h.zeller@acm.org>
Mainstream pull request: https://github.com/nothings/stb/pull/1736

(cherry picked from commit b5ed0d0138)
2025-04-23 17:55:24 +03:00
Sam Lantinga
f5ac58c9f4 Added tests to cover invalid surface blits
Reproduction case for https://github.com/libsdl-org/SDL/issues/12844

(cherry picked from commit 89d7d406ab)
2025-04-22 13:06:36 -07:00
Petar Popovic
c1779ca4a5 SDL_BlitSurfaceScaled(): Do not divide by zero
(cherry picked from commit fe849f1572)
2025-04-22 13:06:35 -07:00
Petar Popovic
6d8309f72e SDL_BlitSurfaceScaled(): Do not blit if surfaces have no pixel data
(cherry picked from commit 8017d38adc)
2025-04-22 13:06:35 -07:00
Sam Lantinga
cf95db46a7 Renamed SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8 to SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER
Typically we will name the property with the function that is used to set it, and document the range of values.

(cherry picked from commit 18fbe6a92f)
2025-04-22 10:28:43 -07:00
Petar Popovic
b8abfeb7f3 SDL_BlitSurface() comment: Remove sentence about final blit rect being stored in srcrect and dstrect
(cherry picked from commit a696b108ac)
2025-04-22 10:21:54 -07:00
Sam Lantinga
014e24e1a8 Removed incorrect documentation for SDL_RenderViewportSet()
Closes https://github.com/libsdl-org/SDL/pull/12854

(cherry picked from commit c076b0d17f)
2025-04-22 10:17:57 -07:00
Cameron Gutman
e42071a47c x11: Send key events for dead keys consumed by the IME
This matches the Wayland backend and what apps originally written for SDL2 are expecting.

(cherry picked from commit 47162a4168)
2025-04-22 09:18:46 -07:00
Sam Lantinga
1543f523b7 Updated documentation for SDL_HINT_GPU_DRIVER
(cherry picked from commit 3aed80cd82)
2025-04-22 08:58:58 -07:00
Frank Praznik
f2d0e965fc wayland: Account for timer rollover when calculating the elapsed time for key repeats.
The 32-bit millisecond timer can roll over after about 49 days, so this needs to be accounted for.

(cherry picked from commit 5bd1578a45)
2025-04-22 10:46:34 -04:00
Frank Praznik
f782278d20 cocoa: Use CGFLOAT_MAX for unbounded max window dimensions
(cherry picked from commit 10f51da28d)
2025-04-21 21:11:07 -04:00
Frank Praznik
3b17d08eb2 win32: Check internal data when positioning child windows
Under certain circumstances, processing events may try to position a child before it is fully initialized. Check the internal data before proceeding.

(cherry picked from commit 9da46bc37f)
2025-04-16 12:50:34 -04:00
Sam Lantinga
18d367afd2 Fixed process I/O redirection to NUL on Windows
(cherry picked from commit 4093e4a193)
2025-04-11 15:45:33 -07:00
Sam Lantinga
9a4faf9ab9 Add the CREATE_NO_WINDOW flag for background processes
Fixes https://github.com/libsdl-org/SDL/issues/12097

(cherry picked from commit c025fdbb7c)
2025-04-11 15:45:33 -07:00
Sam Lantinga
cb0ba020d4 Don't reset the render target when invalidating GPU renderer cache state
Fixes https://github.com/libsdl-org/SDL/issues/12646

(cherry picked from commit f35a2736b7)
2025-04-11 09:24:38 -07:00
Sam Lantinga
f705e2f9f7 Fixed conflict when linking both SDL and hidapi statically
Fixes https://github.com/libsdl-org/SDL/issues/12790

(cherry picked from commit 98e76d283f)
2025-04-10 09:58:13 -07:00
Patrick José Pereira
e76bffa183 Add Turtle Beach VelocityOne
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
(cherry picked from commit f6db5ba4c9)
2025-04-10 09:48:58 -07:00
Adam Kewley
a4e19dc567 [Windows]: dialog: Add OFN_OVERWRITEPROMPT to save dialogs (#12782)
(cherry picked from commit 0add037803)
2025-04-08 21:34:23 -07:00
Sam Lantinga
4e1282617a Fixed non-XBox controllers being detected as Series X controllers
First make sure we have an XBox One controller before checking whether it's a Series X/S controller.

(cherry picked from commit 93ac1e6894)
2025-04-08 12:21:34 -07:00
Sam Lantinga
f102ff16a2 Don't treat the Keychron K1 Pro System Control keyboard as a joystick
Fixes https://github.com/libsdl-org/SDL/issues/12758

(cherry picked from commit d29bb902f3)
2025-04-08 11:08:55 -07:00
Ozkan Sezer
50935a9d41 fix sdlgenblit.pl so that it actually matches the generated source
(cherry picked from commit b0a0d236d8)
2025-04-08 18:24:40 +03:00
Sam Lantinga
a1dde664d1 Updated version documentation to match SDL 3.x practice
(cherry picked from commit cccad933a0)
2025-04-07 10:23:27 -07:00
Frank Praznik
ba5325fba1 x11/wayland: Ignore redundant restore and fullscreen leave requests when showing the window
The window may be initially maximized or made fullscreen by the window manager for various reasons, such as automatically declaring a window that precisely fills the usable desktop space as maximized, or a "kiosk-mode" automatically making the window fullscreen.

Don't redundantly make restored or unset fullscreen calls when initially showing a window, or the expected state can be unset.

(cherry picked from commit adad7dcae0)
2025-04-07 12:38:12 -04:00
Frank Praznik
e225a10ea8 x11: Only enable _NET_WM_SYNC_REQUEST for OpenGL windows
It doesn't work well with Vulkan, and Vulkan windows may not have the Vulkan flag set in all circumstances, so only enable it if we explicitly know that OpenGL is being requested instead.

(cherry picked from commit 646f1f243f)
2025-04-05 15:45:35 -04:00
Evan Hemsley
c4fba75a12 GPU Vulkan: Clean up in Submit in headless mode (#12744)
(cherry picked from commit 33f90f2e41)
2025-04-04 14:27:53 -07:00
Lucas Murray
5b052e6f8c GPU: Add missing error code to VkErrorMessages()
(cherry picked from commit 906c6c7516)
2025-04-04 07:39:44 -07:00
Lucas Murray
d89c3489f8 GPU: The D3D12 blit shaders are DXIL
(cherry picked from commit 205c34c62a)
2025-04-04 07:39:43 -07:00
Sam Lantinga
a447863e4f Set a default shader entry point
The default should be the entrypoint generated by SDL_shadercross. That way it doesn't need to be hand-specified in the common workflow.

(cherry picked from commit dcb97a5f49)
2025-04-04 07:39:16 -07:00
Lucas Murray
34db21cea8 GPU: Don't pass null properties to SDL_CopyProperties()
(cherry picked from commit 300013cea7)
2025-04-04 07:36:30 -07:00
Evan Hemsley
943226edc1 GPU Vulkan: Fix recursive Submit calls causing defrag to fail (#12718)
---------

Co-authored-by: Sam Lantinga <slouken@libsdl.org>
(cherry picked from commit b53e7b4478)
2025-04-03 15:01:43 -07:00
Frank Praznik
281494676a x11: Send a restored event before entering fullscreen
Ensures that the maximized flag is cleared on fullscreen windows.

(cherry picked from commit ca613b9d8f)
2025-04-03 17:02:43 -04:00
Frank Praznik
413b55deb7 x11: Don't set the hidden flag when minimizing windows
On non-compositing window managers, XIconifyWindow can trigger map/unmap events, which would toggle the window hidden/shown state. This should not be done, as a hidden window in SDL is equivalent to a withdrawn window in X, and SDL will try to set/reset state when it is shown again.

Unless the window is explicitly being withdrawn via X11_HideWindow(), set unmapped windows to the minimized/occluded state, and send a restored event when mapped again.

(cherry picked from commit 667b706a93)
2025-04-03 16:53:33 -04:00
Sam Lantinga
8222513f63 Added special handling for SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY
This hint needs to persist outside of the normal application flow, so use the environment to set the initial value, and then save the value set via SDL_SetHint() after that.

Fixes https://github.com/libsdl-org/SDL/issues/12677

(cherry picked from commit 6bb16296b0)
2025-04-03 11:34:03 -07:00
Sam Lantinga
2dd20ce8e7 Fixed building for Xbox One
Fixes https://github.com/libsdl-org/SDL/issues/12714

(cherry picked from commit 756b455d3a)
2025-04-03 09:10:01 -07:00
SDL Wiki Bot
d308df6d62 Sync SDL3 wiki -> header
[ci skip]

(cherry picked from commit 008690d016)
2025-04-03 08:54:27 -07:00
Sam Lantinga
f51b88e6b5 Note that you might get a different size window than you expect
(cherry picked from commit df32827407)
2025-04-03 08:54:27 -07:00
Sam Lantinga
7cb0fa5c56 Fixed documentation for SDL_GL_*_SIZE
(cherry picked from commit ab34ea5a26)
2025-04-02 22:32:39 -07:00
Sam Lantinga
976c92a2fb Added support for the HORI Taiko No Tatsujin Drum Controller
(cherry picked from commit 82b245d13a)
2025-04-02 08:30:55 -07:00
Frank Praznik
15db51d7ff cocoa: Ignore both clicks and motion on tooltip windows
(cherry picked from commit ad2584813f)
2025-04-01 22:50:33 -04:00
Frank Praznik
4aa4e6a18e x11: Enable legacy synchronization for external window resize and move events
External windows often handle their own events, and SDL implicitly processing events during synchronization can be unexpected and cause issues. For requests that don't change the window state beyond size or position, use the legacy synchronization method that synthesizes events from the window attributes without processing events.

(cherry picked from commit 6e2d3c9b5d)
2025-04-01 21:34:34 -04:00
Sam Lantinga
0759f22a91 More clarification for high DPI support
(cherry picked from commit 4de396734d)
2025-03-31 18:53:57 -07:00
Sam Lantinga
02036ee643 Fixed texture colorspace when creating a texture from a surface
Fixes https://github.com/libsdl-org/SDL/issues/12691

(cherry picked from commit 36fc1c2c9c)
2025-03-31 18:50:45 -07:00
blukai
9109e05f3f fix vulkan vertex buffer indexing
this was causing problems when i was specifying non-zero buffer slots in
`SDL_BindGPUVertexBuffers`, `SDL_GPUVertexAttribute` and
`SDL_GPUVertexBufferDescription`.

`firstSlot + 1` is simply copied over from metal and d3d12 backends.

(cherry picked from commit 512485869c)
2025-03-31 18:42:03 -07:00
Sam Lantinga
2103451d00 Clarify high DPI support and best practices
(cherry picked from commit 2e494fda30)
2025-03-31 16:49:55 -07:00
Sam Lantinga
b6db091d60 Fixed A/B/X/Y buttons on Nintendo 3DS
Fixes https://github.com/libsdl-org/SDL/issues/12690

(cherry picked from commit 44faac2921)
2025-03-31 15:38:16 -07:00
Sam Lantinga
9827653c38 Updated to version 3.2.11 for development 2025-03-31 13:54:19 -07:00
Sam Lantinga
877399b2b2 Updated to version 3.2.10 for release 2025-03-31 13:12:19 -07:00
Frank Praznik
3f059376ac wayland: Commit the confinement region upon creation
This may prevent the pointer from escaping small regions if moving quickly.

(cherry picked from commit 6b1d6bfbe7)
2025-03-31 11:59:29 -04:00
Frank Praznik
30a6d01cc5 wayland: Defer creating cursor confinement regions until the surface is mapped
Otherwise, the confinement area will be lost if the window is recreated when initializing the renderer.

(cherry picked from commit 266ee41c86)
2025-03-31 11:59:29 -04:00
SDL Wiki Bot
b6fb47aa70 Sync SDL3 wiki -> header
[ci skip]

(cherry picked from commit cb1d79db39)
2025-03-31 08:53:19 -07:00
Vittorio Romeo
7ecae856e5 Update include/SDL3/SDL_power.h
Co-authored-by: Sam Lantinga <slouken@libsdl.org>
(cherry picked from commit 088ad66f70)
2025-03-31 08:53:19 -07:00
Vittorio Romeo
5db7694f22 Add performance disclaimer in SDL_GetPowerInfo documentation
(cherry picked from commit 032d696021)
2025-03-31 08:53:19 -07:00
Sam Lantinga
366294e1c5 Fixed build
(cherry picked from commit 0d04e9ea6a)
2025-03-30 21:35:22 -07:00
Sam Lantinga
4d966ff546 Set the alpha opaque when blending to an RGB format
Fixes the render_testRGBSurfaceNoAlpha automated test in sdl2-compat

(cherry picked from commit 7bb95bde49)
2025-03-30 21:30:04 -07:00
Sam Lantinga
6b665066f0 Added SIMD blitters for 8888 -> 8888 format conversion
(cherry picked from commit e20e27e1fb)
2025-03-30 21:29:48 -07:00
Frank Praznik
519011f271 x11: Popup positions after constraining are in the window-relative space, not global
(cherry picked from commit 210b317d8d)
2025-03-29 11:11:24 -07:00
Andrei Tsurkan
5c224a3221 fix missing AVFoundation in CMakeLists.txt
(cherry picked from commit f7a89d19c6)
2025-03-29 08:45:26 -07:00
Sam Lantinga
4b8c38e7ba Temporarily disable DwmFlush()
For some reason this locks up the Windows compositor when called by Steam. I'm disabling it for now until we understand why and whether this can cause issues for other applications as well.

(cherry picked from commit a23f97483f)
2025-03-28 20:32:28 -07:00
Cameron Gutman
16f6c1058c gamepad: Fix inability to disable SDL_EVENT_GAMEPAD_UPDATE_COMPLETE events
(cherry picked from commit 712c76fdc1)
2025-03-28 17:19:49 -05:00
Green Sky
7939309520 video: fix surface leak when duplicating mjpeg
(cherry picked from commit eb918af3dc)
2025-03-28 13:19:29 -07:00
Sam Lantinga
cec6073085 Updated link to PSP Hello World
(cherry picked from commit 304cb742881c5da76d41f28181624f8c2aafa05a)
2025-03-27 12:19:51 -07:00
Frank Praznik
a9f121f3f7 cocoa: Clear pending state on fullscreen switch failures
The window failing to enter/exit fullscreen notifications don't necessarily imply anything about the actual state of the window. On failure, dump pending events, and don't presume anything about the current window state, as it will be handled by subsequent enter/leave notifications.

(cherry picked from commit 09fff161e9)
2025-03-27 11:59:43 -04:00
Frank Praznik
361218ce15 cocoa: Re-add sync timeout
This should never happen, but it's a failsafe against future bugs or odd configurations

(cherry picked from commit 05d23cae73)
2025-03-27 11:59:09 -04:00
Ryan C. Gordon
04dcfada00 audio: Allow PipeWire and PulseAudio streams to migrate to other sinks.
SDL still manages hotplug and default device management here, but if a user
wants to use an external tool, such as `pactl move-sink-input`, to put it
onto a different device, they probably know what they're doing and we
shouldn't stop them.

If this turns out to have some unexpected consequences, though, we can revisit
the change.

Fixes https://github.com/libsdl-org/sdl2-compat/issues/367

(cherry picked from commit 4c035a1fd8)
2025-03-27 11:22:59 -04:00
Sam Lantinga
d73ad0ef18 Don't send relative motion while in a modal loop
This fixes queuing up a bunch of relative motion events while moving or resizing a window.

(cherry picked from commit 2e61b41652)
2025-03-27 08:10:58 -07:00
Ryan C. Gordon
a1b888f622 alsa: Don't start the hardware until the device thread is ready to do work.
Otherwise, in the time it takes the thread to start and other init tasks to
complete, we tend to get an underrun on some systems, which ALSA logs to
stderr.

So this is moved to an InitThread implementation, which runs from the device
thread, right before it begins its main loop.

Reference PR #12632.

(cherry picked from commit ae17b04c0d)
2025-03-26 15:01:04 -04:00
Ryan C. Gordon
d6267afcb9 audio: Feed output devices immediately, instead of waiting upfront.
This prevents the waste of an initial buffer of audio on many backends, and is
hopefully harmless on all of them.

Reference PR #12632.

(cherry picked from commit 41636959d2)
2025-03-26 14:58:54 -04:00
Ryan C. Gordon
b8325be9cf pulseaudio: Fixed typo in commented-out debug logging.
(cherry picked from commit 48d4104ecb)
2025-03-26 14:58:46 -04:00
Sam Lantinga
e77ef86f09 Added mappings for the NSO N64/SEGA/SNES controllers
These are used on Linux when the HIDAPI driver isn't available.

(cherry picked from commit e28974124a)
2025-03-25 14:46:30 -07:00
Sam Lantinga
951ba597ed Fixed face buttons for the NSO SNES controller under the HIDAPI driver
(cherry picked from commit b88200b797)
2025-03-25 14:46:30 -07:00
Frank Praznik
ab5e178dab Fix spelling mistake in documentation
(cherry picked from commit b45ed98ae9)
2025-03-25 12:39:54 -04:00
Frank Praznik
04dace6c75 x11: Send the _XWAYLAND_MAY_GRAB_KEYBOARD message when grabbing the keyboard
GNOME requires this to allow keyboard grabs on XWayland. Otherwise, XGrabKeyboard will still report success, but shortcuts won't be inhibited.

See 5f132f3975

(cherry picked from commit 716e33f106)
2025-03-25 12:36:35 -04:00
Frank Praznik
013918cd83 cocoa: Properly set the pending fullscreen spaces state when in a transition
(cherry picked from commit b520cde18f)
2025-03-24 23:26:00 -04:00
Carl Åstholm
996466e855 Check if GL_OES_EGL_image_external is supported before trying to use it
(cherry picked from commit dd9b9d4513)
2025-03-24 19:52:54 -07:00
Carl Åstholm
61e7878ac0 Document SDL_malloc alignment guarantees
(cherry picked from commit 7ec13a2ead)
2025-03-24 19:41:08 -07:00
Frank Praznik
c067cb4e7d wayland: Fix global mouse position retrieval
(cherry picked from commit 8cb303126f)
2025-03-24 19:06:35 -04:00
Sam Lantinga
38697dd812 Fixed mixed trigger and body rumble for Xbox controllers on Windows
Fixes https://github.com/libsdl-org/SDL/issues/12095

(cherry picked from commit b6ca03611f)
2025-03-24 11:07:12 -07:00
Cameron Gutman
f03572335a keyboard: Don't check text input on a null window
(cherry picked from commit c3a3a11db4)
2025-03-23 23:53:19 -05:00
Frank Praznik
d8837edfa2 wayland: Scale accelerated relative pointer coordinates with emulated resolutions
The accelerated relative coordinates are always relative to the desktop resolution, and need to be scaled with emulated fullscreen resolutions for mouse movement to remain stable. Otherwise, pointer speeds will be too fast on emulated resolutions below the desktop resolution, and too slow on those above.

(cherry picked from commit 027df89ed3)
2025-03-22 14:36:05 -04:00
expikr
e5f8043037 chore: rename integer mode field names
(cherry picked from commit f52f982b1e)
2025-03-22 09:37:33 -07:00
Sam Lantinga
134b57f6f5 Improve move/resize visual smoothness on Windows
Fixes https://github.com/libsdl-org/SDL/issues/12528

(cherry picked from commit 6b13d69105)
2025-03-21 16:47:29 -07:00
Marcin Serwin
072e760197 audio: hold floating point exceptions when using neon
(cherry picked from commit 4fcef9074b)
2025-03-21 15:09:24 -07:00
Frank Praznik
d37a3e2a71 x11: Fix backwards _NET_WM_SYNC_REQUEST init check
(cherry picked from commit b493e29a81)
2025-03-21 15:34:26 -04:00
Sam Lantinga
ed8e7e85f0 SDL_ClaimWindowForGPUDevice() should fail for transparent windows
The GPU API doesn't currently support transparent windows (transparent swapchain effects doesn't seem possible on D3D12) so we should explicitly fail so users don't expect transparency and then not get it.

Fixes https://github.com/libsdl-org/SDL/issues/12410

(cherry picked from commit 2fbb583290)
2025-03-21 12:15:09 -07:00
Frank Praznik
eb9faad124 cocoa: Fix zoom check when leaving fullscreen
Non-resizable windows will always report as zoomed, so isZoomed is not a reliable check here.

(cherry picked from commit 79081a178f)
2025-03-21 14:44:53 -04:00
Frank Praznik
3ed80843fe video: Fix boolean logic for getting the pending window position
(cherry picked from commit 03cdd297e0)
2025-03-21 11:36:46 -07:00
hwsmm
4029521a63 Don't send text event while ctrl/alt is held on X11/Wayland
(cherry picked from commit ac5b2b6102)
2025-03-20 21:27:22 -07:00
Sam Lantinga
f971a59746 Fixed DebugLogRenderCommands() output
(cherry picked from commit 758eb256b9)
2025-03-20 21:25:23 -07:00
Sam Lantinga
5836266bfb We need to rebind D3D12 resources after updating them
Fixes https://github.com/libsdl-org/SDL/issues/12544

(cherry picked from commit 4ceb02434b)
2025-03-20 20:22:33 -07:00
Max
ed893bde04 Updates SDL_SetEventFilter code snippet to SDL3
SDL_EventFilter points to a function that now returns a bool

(cherry picked from commit 817260c73d)
2025-03-20 16:50:53 -07:00
Carl Åstholm
a934a36a18 emscripten: Don't use legacy JS library functions for assertions
(cherry picked from commit 54f5b73333)
2025-03-20 16:32:40 -07:00
Sam Lantinga
59857acd08 Always show the on-screen keyboard on Steam Deck
Steam will eventually have smarts about whether a keyboard is active and will igore the request appropriately.

Fixes https://github.com/libsdl-org/SDL/issues/12595

(cherry picked from commit 03a53ce0d1)
2025-03-20 16:30:04 -07:00
Sam Lantinga
8129b637f3 A Steam Controller might be generating keyboard input
We can't use keyboard input as a signal about whether a keyboard is attached. There might be keyboard input from any number of generated inputs or non-keyboard devices.

(cherry picked from commit 8caeaaacdd)
2025-03-20 16:30:04 -07:00
Sam Lantinga
9e1675671d Show the on-screen keyboard if we don't have active keyboard input
Active keyboard input is based on the input the user has most recently sent.

Fixes https://github.com/libsdl-org/SDL/issues/12595

(cherry picked from commit cbb83be895)
2025-03-20 16:30:04 -07:00
SDL Wiki Bot
d39d951f89 Sync SDL3 wiki -> header
[ci skip]

(cherry picked from commit 67b4c3a156)
2025-03-20 16:30:04 -07:00
Ryan C. Gordon
10ed6f49a9 asyncio: SDL_LoadFileAsync was not null-terminating the file data.
(cherry picked from commit 10072bb07d)
2025-03-20 16:30:04 -07:00
Ryan C. Gordon
c2c848a752 SDL_audio.h: Fixed typos in docs.
(cherry picked from commit 85435d5a14)
2025-03-20 16:30:04 -07:00
Sam Lantinga
8b191c3ca6 Fixed typo in build.gradle
(cherry picked from commit fe024b8fe3)
2025-03-20 11:22:20 -07:00
Sam Lantinga
06a412cd68 Fixed gradle deprecation warnings
"Space-assignment syntax in Groovy DSL has been deprecated. This is scheduled to be removed in Gradle 10.0"

(cherry picked from commit bf7b9b020e)
2025-03-20 11:05:56 -07:00
Sam Lantinga
b74609d5f3 Use the android-21 SDK as documented in README-android.md
(cherry picked from commit ac28702504)
2025-03-20 11:05:56 -07:00
Sam Lantinga
d8756582f9 Don't create surfaces with invalid pixel formats
Fixes https://github.com/libsdl-org/SDL/issues/12556

(cherry picked from commit 476e7e54cb)
2025-03-20 09:43:40 -07:00
Sam Lantinga
ff90984dc3 Fix illegal calls to DwmGetWindowAttribute()
DWMWA_WINDOW_CORNER_PREFERENCE and DWMWA_BORDER_COLOR are only supported for DwmSetWindowAttribute(), they can't be queried.

Fixes https://github.com/libsdl-org/SDL/issues/12206
Closes https://github.com/libsdl-org/SDL/pull/12209

(cherry picked from commit f2ed5c7a1b)
2025-03-19 22:03:18 -07:00
Sam Lantinga
81952f9f96 Windows allows windows to be resized to zero height.
Changed the window client rect validation to take this into account.

Fixes https://github.com/libsdl-org/SDL/issues/9796

(cherry picked from commit 96bf12444c)
2025-03-19 21:23:06 -07:00
Sam Lantinga
d0122ff624 Make sure we're getting called for the correct window
Fixes https://github.com/libsdl-org/SDL/issues/12525

(cherry picked from commit 47b0c75470)
2025-03-19 20:22:52 -07:00
Sam Lantinga
7a36aa37aa Fixed crash if a window couldn't be created on Windows
Fixes https://github.com/libsdl-org/SDL/issues/11482

(cherry picked from commit 3415bc920a)
2025-03-19 20:10:49 -07:00
Dragon-Baroque
464cb0ab6e The posix4 library has been merged into the libc library
(cherry picked from commit 07e4dea693)
2025-03-19 18:41:51 -07:00
Evan Hemsley
ac21e3ef3f GPU Vulkan: Fix render pass race (#12587)
(cherry picked from commit c696e93180)
2025-03-19 13:34:26 -07:00
Frank Praznik
a5b51669fb time: Fix compilation on Solaris
The tm_gmtoff field of the broken-down time 'tm' struct wasn't formally standardized until POSIX.1-2024, but practically it has been available on desktop *nix platforms such as Linux/glibc, FreeBSD, OpenBSD, NetBSD, OSX/macOS (NextStep before that), and others since the 1990s. The notable exception is SunOS/Solaris, where the timezone offset must still be retrieved in the strictly POSIX.1-2008 compliant way.

(cherry picked from commit 7b93a744c8)
2025-03-19 12:27:39 -04:00
Carl Åstholm
0ac030549b emscripten: Fix undefined behavior in opengles2 renderer
(cherry picked from commit 14deef997c)
2025-03-18 19:19:01 -07:00
Frank Praznik
6f1afe7084 video: Send pending coordinates for moved, hidden windows
Some backends can't actually position a window until it is shown/mapped, so assume that it will be where it was asked to be as long as it is hidden.

(cherry picked from commit d66483dfcc)
2025-03-18 19:56:25 -04:00
Sam Lantinga
6302589829 Use an autoreleasepool in Cocoa_GetDisplayUsableBounds()
Fixes https://github.com/libsdl-org/SDL/issues/12571

(cherry picked from commit 8b924df48b)
2025-03-18 14:40:01 -07:00
Sam Lantinga
3225d31679 Fixed building with SDL_LEAN_AND_MEAN
Fixes https://github.com/libsdl-org/SDL/issues/12578

(cherry picked from commit 82335fd0e9)
2025-03-18 09:55:46 -07:00
Arnoldo Adonaí Barón Robles
ae05ab280d Fix Vulkan error check
(cherry picked from commit a551c2a6d7)
2025-03-17 22:11:21 -07:00
Caleb Cornett
51a6cb2cf5 gpu: Fix MTLLibrary dispatch data destructor
(cherry picked from commit 6d0fb0a2e6)
2025-03-17 18:54:30 -07:00
Evan Hemsley
daf468e141 GPU: Fix Vulkan backend never checking deallocations (#12567)
---------

Co-authored-by: Sam Lantinga <slouken@libsdl.org>
(cherry picked from commit 0bd70684b3)
2025-03-17 13:59:47 -07:00
Sam Lantinga
cd673c8254 Fixed raw input device GUIDs changing randomly between runs
On Windows 11, apparently HidD_GetManufacturerString() and HidD_GetProductString() can return TRUE without actually filling in any string data.

Fixes https://github.com/libsdl-org/SDL/issues/12566

(cherry picked from commit 4fc9509ab7)
2025-03-17 13:57:15 -07:00
Sam Lantinga
3f13c0b36d Fixed crash if info->path is NULL
(cherry picked from commit 715301cef5)
2025-03-17 09:46:57 -07:00
Cameron Gutman
3e34720851 mouse: Allow use of integer coordinates with fractional wheel events
SDL 2.0.18 added preciseX/Y to mouse wheel events, which we cannot
emulate in sdl2-compat without a mechanism to control integer position
and scroll deltas separately.

(cherry picked from commit aad1e35162)
2025-03-15 13:44:19 -07:00
Sam Lantinga
0799237d74 Added unaligned version of SDL_ConvertPixels_SwapNV_std()
Fixes https://github.com/libsdl-org/SDL/issues/12546

(cherry picked from commit 501e71f25f)
2025-03-15 09:25:39 -07:00
Sam Lantinga
53f64e40c4 Fixed SDL_GPUTextureSupportsSampleCount() documentation
Fixes https://github.com/libsdl-org/sdlwiki/issues/751

(cherry picked from commit ffe69fc354)
2025-03-14 09:30:44 -07:00
Frank Praznik
a530df20b2 cocoa: Set the internal window data before calling methods that may result in referencing the internal data
(cherry picked from commit 512d97eaba)
2025-03-12 17:09:37 -04:00
Sam Lantinga
b958189c92 Removed help for obsolete (and removed) command line option
(cherry picked from commit 50a397bb45)
2025-03-12 12:38:52 -07:00
Sam Lantinga
341f910835 Initialize the padding of aligned allocations to zero
Fixes valgrind uninitialized memory errors when doing SIMD blits
e.g. testautomation --filter surface_testScale

(cherry picked from commit 3235a4eb4f)
2025-03-12 11:43:09 -07:00
Joshua T. Fisher
84dff407d4 Fixup the mingw readme cmakelists
(cherry picked from commit 7746a9656e)
2025-03-11 19:43:43 -07:00
Sam Lantinga
21e6c5814c Fixed Nintendo controller face button layout under Steam
(cherry picked from commit 2ce3dfdf1d)
2025-03-10 17:31:12 -07:00
Sam Lantinga
776f0a685c Fixed sscanf("026", "%1x%1x%1x", &r, &g, &b)
Fixes https://github.com/libsdl-org/SDL/issues/12510

(cherry picked from commit be6ed6e9c4)
2025-03-10 14:46:30 -07:00
Sam Lantinga
9f32fafe21 Use sized types when fixing undefined behavior
(cherry picked from commit 24339524c5)
2025-03-10 09:54:05 -07:00
rohlem
74b3b8e9e3 avoid UB (left shift of negative number) in SDL_windowsevents.c
(cherry picked from commit f1d16e9b4d)
2025-03-10 09:54:05 -07:00
Frank Praznik
fa4a9ba74e wayland: Fix enum/boolean comparison and assignment
(cherry picked from commit f2866418d4)
2025-03-09 12:28:39 -04:00
Cameron Gutman
9a6f8a2512 mouse: Add internal integer mouse mode hint for sdl2-compat
Performing this inside SDL3 dramatically simplifies sdl2-compat. See https://github.com/libsdl-org/sdl2-compat/issues/372.

(cherry picked from commit 597bfe6b27)
2025-03-08 19:07:05 -08:00
bobsayshilol
1173bc2dde emscripten: Fix handling of special HTML targets
With ASAN enabled the existing code triggered null-pointer-dereference
in the strcmp since EMSCRIPTEN_EVENT_TARGET_WINDOW is a "fake" pointer
with the value ((const char*)2). In fixing this it was also noticed
that using the #window/#document/#screen targets as mentioned in the
docs fails since document.querySelector() returns null for them and we
should instead be mapping them to the special HTML targets provided.

(cherry picked from commit 65cd2256c5)
2025-03-08 17:16:57 -08:00
TheMode
ada55bd887 Implement SDL_GetSystemRAM and SDL_GetNumLogicalCPUCores for the 3ds (#12494)
(cherry picked from commit 5d804a39d9)
2025-03-08 09:54:43 -08:00
Sam Lantinga
fe97cff7d1 Fixed memory leak in memory leak tracking
(cherry picked from commit 99336ea378)
2025-03-08 09:54:43 -08:00
ds-sloth
8cdeb1a35a Fix n3ds/SDL_syssem.c:SDL_SignalSemaphore (libsdl-org/SDL#12411)
(cherry picked from commit 0306b5a865)
2025-03-07 17:32:05 -08:00
Sam Lantinga
7c82171a85 Fixed pen events on iOS after reinitializing SDL
We weren't resetting apple_pencil_id, so not re-registering it later.

(cherry picked from commit 3353b92a96)
2025-03-07 16:33:09 -08:00
Sam Lantinga
2d2085c80b Add a link to docs/INTRO-mingw.md
(cherry picked from commit d631a3add0)
2025-03-06 16:26:15 -08:00
Joshua T. Fisher
03a4eea0ef Added MinGW Intro readme, touched up CMake and Visual Studio readmes. (#12485)
(cherry picked from commit 04b4577b58)
2025-03-06 16:26:15 -08:00
Sam Lantinga
fec3e2cd45 Removed logic forcing vsync on if setting it off fails
The platforms that needed this (Windows Phone and Windows RT) are no longer supported, and if this is needed in the future it should be done at the renderer level, not here.

Fixes https://github.com/libsdl-org/SDL/issues/12475

(cherry picked from commit b99ff00a95)
2025-03-06 16:18:42 -08:00
Sam Lantinga
2aec1c2ef6 Added support for SDL_PIXELFORMAT_MJPG to SDL_DuplicateSurface()
Fixes https://github.com/libsdl-org/SDL/issues/12472

(cherry picked from commit 4c82b5843e)
2025-03-05 23:39:33 -08:00
Sam Lantinga
b32cd4f84b Make texture scale mode a part of the 2D renderer draw state
Also added texture addressing mode support to the PSP and Vita renderers (untested)

Fixes https://github.com/libsdl-org/SDL/issues/12461

(cherry picked from commit cb099ebd4f)
2025-03-05 22:39:31 -08:00
SDL Wiki Bot
550bdc658a Sync SDL3 wiki -> header
[ci skip]

(cherry picked from commit f01bcaeb17)
2025-03-05 09:13:10 -08:00
Sam Lantinga
d75ba9c2d2 Added SDL_HINT_VIDEO_X11_EXTERNAL_WINDOW_INPUT
(cherry picked from commit fe9bdcf508)
2025-03-05 09:13:10 -08:00
SDL Wiki Bot
2477f7f982 Sync SDL3 wiki -> header
[ci skip]

(cherry picked from commit 9f557941f3)
2025-03-05 07:26:50 -08:00
Sam Lantinga
e454d7d4be Document the thread safety of SDL surface functions
(cherry picked from commit 8f40dad460)
2025-03-05 07:26:49 -08:00
Sam Lantinga
cd8bffb2dd Fixed continuous logging if returning to desktop mode fails on X11
(cherry picked from commit aef240b2e4)
2025-03-04 17:26:03 -08:00
Sam Lantinga
9646e3cc1b Handle XWayland not sending display disconnected events
Also updated X11_CheckDisplaysMoved() to handle multiple X11 screens

Fixes https://github.com/libsdl-org/SDL/issues/12462

(cherry picked from commit e9632c83c7)
2025-03-04 17:26:03 -08:00
Sam Lantinga
1a2362ebf1 Updated to version 3.2.9 for development 2025-03-04 15:07:23 -08:00
Sam Lantinga
f6864924f7 Updated to version 3.2.8 for release 2025-03-04 14:37:06 -08:00
Sam Lantinga
6b3dafa4d3 Fixed crash when restoring the desktop mode on macOS
Fixes https://github.com/libsdl-org/SDL/issues/12460

(cherry picked from commit 80ae3a7516)
2025-03-04 14:34:10 -08:00
Sam Lantinga
5c0c5d2816 Fixed crash unplugging a HIDAPI controller
(cherry picked from commit 5f07347e4f)
2025-03-04 11:42:37 -08:00
Sam Lantinga
de11dd3d60 Make SDL_RegisterEvents() thread-safe
Fixes https://github.com/libsdl-org/SDL/issues/12457

(cherry picked from commit 82552e5b7c)
2025-03-04 10:28:53 -08:00
Frank Praznik
ac09af2600 video: Synthesize fullscreen related moves if the driver does not.
(cherry picked from commit 9f9a442823)
2025-03-04 12:49:56 -05:00
Frank Praznik
26d1afa29c x11: Synthesize fullscreen size events on Openbox
Openbox doesn't send size events when entering fullscreen, so they must be synthesized. This is not desirable on any other window manager, as it can break fullscreen positioning on multi-monitor configurations.

(cherry picked from commit e7abbf158a)
2025-03-04 12:49:56 -05:00
Volian0
6aab3b9da8 Fix for Message Box failing to init on X11 (#12455)
Fixed X11 message boxes failing to initialize, because the proper X Logical Font Description could not be found

(cherry picked from commit debbe1cf75)
2025-03-04 08:34:58 -08:00
Sam Lantinga
d959719a3d Fixed clip rect when logical presentation is enabled
We don't need to include the logical offset, it's already included in the viewport.

Fixes https://github.com/libsdl-org/SDL/issues/12454

(cherry picked from commit 4bb46e93c8)
2025-03-04 08:25:46 -08:00
Sam Lantinga
5a7b17fec5 Added fullscreen_active to better track fullscreen state
This is true if fullscreen is pending or currently active. This is a better check in SDL_SetDesktopDisplayMode() because a fullscreen mode may be pending and complete asynchronously and the window hasn't been set to fullscreen yet.

(cherry picked from commit 7c29c8b266)
2025-03-03 21:19:15 -08:00
Frank Praznik
1d6bb62870 Use _this pointer to reference the video device
(cherry picked from commit 3b9f0dff10)
2025-03-03 19:01:40 -05:00
Frank Praznik
0c3603d893 Check the display device before dereferencing
It can be null if the desktop mode is set early during initial display enumeration.

(cherry picked from commit 0ccf272eea)
2025-03-03 11:25:25 -05:00
Frank Praznik
38a5bca892 video: Handle Cocoa desktop mode switch inhibition in the video layer
The X backend had the same issue, so both Cocoa and X can be handled in the same location.

(cherry picked from commit 6c347cbf33)
2025-03-03 11:05:32 -05:00
Sam Lantinga
70a289076a Don't save temporary mode changes to the desktop mode
Fixes https://github.com/libsdl-org/SDL/issues/12441

(cherry picked from commit 24ec2ed785)
2025-03-03 11:05:20 -05:00
Simon McVittie
1d0ecf982f pipewire: Don't require pw_check_library_version() with Pipewire < 0.3.75
The Debian 12 'bookworm' stable release only has 0.3.65, which is earlier
than the introduction of that symbol. Similarly, Steam Runtime 3 'sniper'
and Steam Runtime 2 'soldier' have a backport of 0.3.65 from Debian 12,
so they have the same limitation.

steamrt/tasks#686

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit d57aa6f7af)
2025-03-03 07:32:51 -08:00
Sam Lantinga
18d93d11e1 Only use VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR on Android
This fixes Nintendo Switch where the identity bit isn't available. We only needed this on Android to automatically handle device user orientation.

(cherry picked from commit 2c7c3d4d7b)
2025-03-02 09:14:12 -08:00
Sam Lantinga
110a832f5c Save and restore error messages when rolling back after failed init
Fixes https://github.com/libsdl-org/SDL/issues/12439

(cherry picked from commit 1a7c206986)
2025-03-02 07:57:36 -08:00
Frank Praznik
6a9e970880 cocoa: Don't overwrite the desktop mode when changing the fullscreen mode
Changing the mode triggers a display reconfiguration event, which will overwrite the desktop mode with the set fullscreen mode, preventing proper restoration when leaving fullscreen. Don't overwrite the desktop mode if the reconfiguration is due to a fullscreen mode switch.

(cherry picked from commit b69201daeb)
2025-03-01 23:43:29 -05:00
Frank Praznik
4e3058ce82 cocoa: Run pending events to completion
Fullscreen spaces and miniaturization will always give us some notification that they succeeded or failed, so the timeout isn't required. This prevents errant timeouts when live-resize is active.

(cherry picked from commit 078d737a27)
2025-03-01 19:34:00 -08:00
Sam Lantinga
bc6307a872 Updated to version 3.2.7 for development 2025-03-01 19:29:51 -08:00
Sam Lantinga
65864190cc Added testpen to the Xcode test project 2025-03-01 18:49:25 -08:00
Sam Lantinga
292e431748 Updated to version 3.2.6 for release 2025-03-01 18:30:34 -08:00
Sam Lantinga
f0cb78e082 Handle XCreateIC() failing when composition UI is enabled
Fixes https://github.com/libsdl-org/sdl2-compat/issues/328
2025-03-01 13:54:07 -08:00
Sam Lantinga
55484ef023 Moved WIN_UpdateMouseCapture() to be with the other mouse functions 2025-03-01 12:54:17 -08:00
Sam Lantinga
020664bd10 Update mouse button state when re-entering a window
Fixes https://github.com/libsdl-org/SDL/issues/12423
2025-03-01 12:54:17 -08:00
Sam Lantinga
b836ad4d4f Fix a root signature mismatch for the D3D12 renderer
The shaders hadn't been rebuilt after c74f273848

Fixes https://github.com/libsdl-org/SDL/issues/12276
2025-03-01 12:02:49 -08:00
Ryan C. Gordon
a88105784f camera: Delete some failure code that should have been removed before. 2025-03-01 14:52:56 -05:00
Brick
f868408a3a Ceil the audio resampling rate to avoid over-estimating output samples.
Reverts 580a496391, fixes #12115
2025-03-01 11:07:55 -08:00
Anonymous Maarten
cbdc93b17f cmake: make sure a SDL3 library is present when not using COMPONENTs 2025-03-01 17:54:45 +01:00
Anonymous Maarten
8a7beca122 camera: clear the spec when closing, so re-opening can probe again 2025-03-01 08:34:01 -08:00
SDL Wiki Bot
ee5f5c9172 Sync SDL3 wiki -> header
[ci skip]
2025-03-01 16:26:19 +00:00
Sam Lantinga
6e4193b743 Note that the file names are UTF-8 encoded 2025-03-01 08:25:31 -08:00
Ozkan Sezer
60c65f9fa4 SDL_camera.c: fix failure-return in SDL_PrepareCameraSurfaces(). 2025-03-01 04:37:02 +03:00
Sam Lantinga
b8c2bc143e Added build dependencies for Arch Linux
These are based on the dependencies listed at:
https://archlinux.org/packages/extra/x86_64/sdl3/
2025-02-28 16:31:10 -08:00
SDL Wiki Bot
7ab1412e20 Sync SDL3 wiki -> header
[ci skip]
2025-02-28 21:21:47 +00:00
Ryan C. Gordon
725af6ad16 camera: Fixed surface formats, etc, for Emscripten backend.
Fixes #12374.
2025-02-28 16:15:01 -05:00
Sam Lantinga
ef23ebfb5a Fixed the cursor clip rect when toggling window borders on macOS 2025-02-28 11:57:34 -08:00
guitarfreak
c682599448 GPU_d3d12: Switched the default swapchain scaling mode to none.
Since there is no option to change it this seems like a much better default value. The stretching behaviour is really off-putting.

The new behavior shows a small black border when resizing the windows. This makes it more in line with the other backends and it's what you would expect to happen as a user.
2025-02-28 11:33:51 -08:00
guitarfreak
ea513fd47c Fixed vulkan gpu backend android orientation behaviour to just work like on iOS.
I changed it so that the OS does the orientation change itself with a potential performance penalty.
This makes it automatically do the right thing, just like on iOS which would make the orientation change behaviour more consistent across different platforms.

But without adding an option to the user, this would disallow the user solving the problem in his in the app/shaders and saving some performance.

It's up to you to decide what to do. But I changed this in my local copy of the source for my use case.
But this also
2025-02-28 07:34:16 -08:00
Elbagast
87b1c9736f Fix pen generated mouse events not having SDL_PEN_MOUSEID (#12392)
* Update SDL_mouse.c

Stop a mouseID of SDL_PEN_MOUSEID being discarded when dispatching mouse events. I'm not sure if this enough to fix the lack of SDL_PEN_MOUSEID being emitted.

* Update SDL_mouse.c

Since we test for touch input here we also test for pen input in the same way.

* Stop duplicate synthetic touch events

If SDL_HINT_PEN_MOUSE_EVENTS and SDL_HINT_MOUSE_TOUCH_EVENTS are both enabled, the pen generated synthetic mouse event will then produce a touch event without this additional check.

This requires the previous commits in order to do anything since it needs to be able to identify those pen generated mouse events.
2025-02-27 20:45:27 -05:00
Wim Taymans
a44107540d sysjoystick: don't leak fd on error 2025-02-27 19:49:46 -05:00
Wim Taymans
9a802797d2 SDL_pen: fix eraser check
It looks like a copy and paste error.
2025-02-27 19:49:46 -05:00
SDL Wiki Bot
54c7aa9c90 Sync SDL3 wiki -> header
[ci skip]
2025-02-28 00:42:06 +00:00
Ryan C. Gordon
35e8cf8ee6 render: allow render targets to use logical presentation.
Fixes https://github.com/libsdl-org/sdl2-compat/issues/279
2025-02-27 19:41:11 -05:00
Sam Lantinga
281f0fae1c Include the VID/PID of generic keyboard/mouse devices on Windows 2025-02-27 14:03:39 -08:00
Frank Praznik
d09bf56818 clipboard: Cleanup coding style 2025-02-27 12:35:37 -05:00
Frank Praznik
edaf447678 tests: Add showing/setting the primary selection text to testclipboard 2025-02-27 12:35:37 -05:00
Frank Praznik
7b9036bea6 wayland: Don't overwrite clipboard data with the primary selection text
Primary selection text is handled separately, and shouldn't clobber the clipboard data.
2025-02-27 12:35:37 -05:00
Ryan C. Gordon
f7cadcba84 examples: Use SDL_GetAudioStreamQueued, not SDL_GetAudioStreamAvailable.
The "available" side is at the mercy of whatever format the hardware wants,
but we control what we queued.

Fixes #12403.
2025-02-27 11:46:56 -05:00
Alexander Batalov
b3336c5a73 Match style 2025-02-27 07:10:09 -08:00
Alexander Batalov
2b784b5bf6 Fix SDL_GlobDirectory 2025-02-27 07:10:09 -08:00
Sam Lantinga
eb89d0c8c3 Don't put wired Switch Pro controllers into simple report mode
This stops the controller from sending input or responding to queries until it's unplugged.
2025-02-26 17:54:43 -08:00
Sam Lantinga
1ea99bc904 Early out if setting a duplicate window title
Setting the window title is an expensive windowing operation, so short circuit it if possible.
2025-02-26 17:10:41 -08:00
SDL Wiki Bot
56e2955b6a Sync SDL3 wiki -> header
[ci skip]
2025-02-26 21:03:33 +00:00
Sam Lantinga
cc984c9735 Added a mapping for the 8BitDo SN30 Pro+ controller on macOS
This mapping is for Android mode (Start + B at startup)
Fixes https://github.com/libsdl-org/SDL/issues/12126
2025-02-26 12:24:47 -08:00
Sam Lantinga
ba88b6aa06 Fixed reliability of initializing Switch controllers on macOS
It looks like both macOS (15.1.1) and SDL are trying to talk to the controller at the same time, which can cause interleaved replies or even locking up the controller. Waiting a bit before talking to the controller seems to take care of this.
2025-02-26 12:24:47 -08:00
Sam Lantinga
66ecdc69ac Don't update the report mode until the related hint is set
Fixes https://github.com/libsdl-org/SDL/issues/12404
2025-02-26 12:24:47 -08:00
Frank Praznik
fab52b578f wayland: Ensure that color descriptions are always retrieved 2025-02-26 15:15:44 -05:00
jsoulier
9464aaa8af Change D3D12 GPU backend to respect has_depth_stencil_target 2025-02-26 10:16:50 -08:00
Sam Lantinga
cf819ca818 Don't allow further operations on properties while we're destroying them
Fixes https://github.com/libsdl-org/SDL/issues/12407
2025-02-26 08:34:14 -08:00
Sam Lantinga
e012573766 Don't fixup mappings for Joy-Con controllers
They don't have a D-pad mapping, so look at the paddles instead to see whether we need to fix up the mapping.

Fixes https://github.com/libsdl-org/SDL/issues/12232
2025-02-25 19:14:18 -08:00
Sam Lantinga
34c3734953 Fixed opening one Joy-Con when the other is visible but disconnected
This can happen on Windows when the controller is turned off directly. It still shows up in the device list and you can send packets to it, but it's off and doesn't respond. We'll mark this device as broken and open the other as a single Joy-Con.
2025-02-25 19:14:18 -08:00
Sam Lantinga
049a7a04de Wake the main thread for main function dispatch
Also added a test case to catch the main thread waiting indefinitely when a function is pending.

Fixes https://github.com/libsdl-org/SDL/issues/12390
2025-02-25 12:50:41 -08:00
hwsmm
f0f593f04b Embed a description about Wayland clipboard instead of a link
Co-authored-by: Frank Praznik <frank.praznik@gmail.com>
2025-02-25 14:33:33 -05:00
hwsmm
bb748ef2d9 Don't cleanup clipboard in SDL_SendClipboardUpdate on Wayland 2025-02-25 14:33:33 -05:00
SDL Wiki Bot
38a73a1783 Sync SDL3 wiki -> header
[ci skip]
2025-02-25 18:29:56 +00:00
Sam Lantinga
85a302550d Set an error message if the rect passed to SDL_RenderReadPixels() is entirely outside the viewport 2025-02-25 10:28:57 -08:00
Sam Lantinga
29df99ee38 Clarified SDL_RenderReadPixels() documentation
Clarified that the rect to be read is clipped against the current viewport, not actually relative to it.

Also added a note for people using SDL_SetRenderLogicalPresentation() so they know they have to map between logical space and render space if they want to read back.
2025-02-25 10:28:57 -08:00
cosmonaut
2f77558bad fix comment 2025-02-25 09:44:10 -08:00
cosmonaut
44f1ec35c4 GPU: Make Vulkan transfer buffers dedicated allocs 2025-02-25 09:44:10 -08:00
Sam Lantinga
1c2189c7c9 strings.h isn't available in Windows environments
I believe this header isn't necessary for clang-tidy, string.h has all the functions we care about.

Fixes https://github.com/libsdl-org/SDL/issues/12238
2025-02-25 09:41:50 -08:00
SDL Wiki Bot
ffdca343fb Sync SDL3 wiki -> header
[ci skip]
2025-02-25 16:58:12 +00:00
Sam Lantinga
ac5fca4ae5 Clarify the expected usage of SDL_StorageReady()
Fixes https://github.com/libsdl-org/SDL/issues/12201
2025-02-25 08:56:56 -08:00
SDL Wiki Bot
fc365e945a Sync SDL3 wiki -> header
[ci skip]
2025-02-25 16:39:56 +00:00
Sam Lantinga
ad840e8796 Better document that main functionality is in SDL_main.h
Fixes https://github.com/libsdl-org/SDL/issues/12159
2025-02-25 08:38:39 -08:00
SDL Wiki Bot
bb8dcf08e7 Sync SDL3 wiki -> header
[ci skip]
2025-02-25 15:54:44 +00:00
Sam Lantinga
6980325310 Added support for the "%n" sscanf format specifier 2025-02-24 20:02:59 -08:00
Sam Lantinga
e6a24fcbb5 fix stbi__parse_png_file() reading too much bytes (thanks @miniupnp!)
just "rewind" the bytes that have been read past the IEND chunk.
2025-02-24 17:29:25 -08:00
Sam Lantinga
db4e6c1931 Cocoa metal layers need their size updated before renderer updates
Also refactored event watch code so it can be shared between internal window event dispatch and public event watchers.

Fixes https://github.com/libsdl-org/SDL/issues/12376
2025-02-24 15:37:13 -08:00
SDL Wiki Bot
0a592b78c1 Sync SDL3 wiki -> header
[ci skip]
2025-02-24 23:12:58 +00:00
Tomasz Pakuła
58388e8db4 Add SDL_HINT_JOYSTICK_HAPTIC_AXES
Allows users to overwrite the number of haptic axes defined for a given
joystick. Also supports a "wildcard" VID:PID of `0xFFFF/0xFFFF`
2025-02-24 15:12:04 -08:00
Ethan Lee
db817a37f4 gpu: Fix forward declaration and inclusion of PrivateGPUDriver 2025-02-24 15:46:39 -05:00
zopsicle
a7bc6c5e08 gpu: initialize VkDebugUtilsLabelEXT::color
Fixes #12383.
2025-02-24 11:51:13 -08:00
Caleb Cornett
60b7faa987 gpu: Validate that reserved struct members are unset 2025-02-24 08:57:09 -08:00
Ralph Sennhauser
2990d142c4 Map additonal Linux keycodes to SDL scancodes
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
2025-02-24 07:53:22 -08:00
Ralph Sennhauser
a0086a5cc4 Add missing scancode names
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
2025-02-24 07:53:22 -08:00
Petter Reinholdtsen
35544df838 Changed PULSEAUDIO_FlushRecording() to only flush audio present when called.
When the flushing is not able to keep up with the audio stream coming in, it
will end up flushing forever and block API clients from getting any audio.

The example program in #9706 get some audio with SDL 3, while do not get any
audio with SDL 2, which I suspect is because SDL 3 is quicker at flushing the audio.
A fix for the SDL 2 issue is available in #12378.
2025-02-24 07:30:36 -08:00
SDL Wiki Bot
deadfe0c98 Sync SDL3 wiki -> header
[ci skip]
2025-02-23 20:20:09 +00:00
Caleb Cornett
0815637cf0 vulkan build fix 2025-02-23 12:19:12 -08:00
Caleb Cornett
ea77472d75 Document/ignore GPU features without universal support 2025-02-23 12:19:12 -08:00
Petar Popovic
ad11c6988c src/io/SDL_asyncio.c:SDL_AsyncIOFromFile(): Fix null-dereference warning 2025-02-23 11:12:24 -08:00
Weng Xuetian
8bfde6755e Remove unnecessary fcitx's devel package dependency in linux doc
Fcitx related support only relies on libdbus.
2025-02-23 10:33:18 -08:00
Frank Praznik
52af81ea17 wayland: Fix mapping borderless windows under libdecor
Additionally, add a warning about calling the frame visibility function universally during the mapping process, as the libdecor Cairo plugin has a bug that will cause a crash in this scenario.
2025-02-23 11:04:29 -05:00
Frank Praznik
1a0a94b501 x11: Accommodate the borders when setting the initial window position 2025-02-23 10:49:40 -05:00
Sam Lantinga
52e64f816c Use SDL C runtime functions in OpenVR driver
Fixes link errors when building with -DSDL_LIBC=OFF
2025-02-22 12:41:03 -08:00
Sam Lantinga
7224b40407 Fix errors when building stb_image with -DSDL_LIBC=OFF
I integrated changes from SDL_image and updated as needed for JPEG memory loading functionality.

Fixes https://github.com/libsdl-org/SDL/issues/12364
2025-02-22 12:41:03 -08:00
Cameron Gutman
945da099ae pipewire: Fix possible deadlock when opening a device
If the pipewire thread invokes output_callback() while we're still
waiting inside PIPEWIRE_OpenDevice(), we will deadlock. The pipewire
thread owns the loop lock and is blocked on the audio device lock,
which cannot be released because pw_thread_loop_wait() needs to
reacquire the loop lock before it can return and allow
PIPEWIRE_OpenDevice() to complete and release the device lock.
2025-02-22 11:37:06 -08:00
Anonymous Maarten
70f657e520 ci: farewell, clang32 on msys2 2025-02-22 19:06:27 +01:00
Sam Lantinga
e50db698e2 Disable all camera drivers if SDL_CAMERA_DISABLED is defined
Fixes https://github.com/libsdl-org/SDL/issues/12182
2025-02-22 09:48:49 -08:00
Sam Lantinga
1ddba3ad55 Replace "8BitDo Tech Ltd" with "8BitDo" in the manufacturer string
Fixes the 8BitDo Micro gamepad so it shows up as "8BitDo Bluetooth Wireless Controller" in keyboard mode over Bluetooth.
2025-02-22 09:19:59 -08:00
Sam Lantinga
fdf72d1e45 Use the keyboard/mouse vendor if available
Fixes the 8BitDo Micro gamepad so it shows up as "8BitDo HID-compliant mouse" and "8BitDo HID Keyboard Device" in keyboard mode over USB.
2025-02-22 09:19:59 -08:00
Sam Lantinga
a811e0ef0f Added support for the 8BitDo Micro gamepad 2025-02-22 09:19:59 -08:00
Sam Lantinga
bc85c55350 testcontroller: create window with high pixel density
This improves the picture quality when running on an iPhone.
2025-02-22 09:02:01 -08:00
Sam Lantinga
75bbcbf87b Added support for Motion JPEG pipewire camera capture 2025-02-22 00:23:03 -08:00
Anonymous Maarten
5c214e5e9c testcamera: SDL_AppQuit destroys state and SDL
This fixes a double-free of SDLTest_CommonState
2025-02-21 23:04:13 -08:00
Anonymous Maarten
03e00cd347 v4l2: map SDL_PIXELFORMAT_MJPG to V4L2_PIX_FMT_MJPEG 2025-02-21 23:04:13 -08:00
Sam Lantinga
fcd41c1d2c Check desired window area when checking zoom state
isZoomed returns true if the window has the size and position that it would if it were maximized, so we need to check to see if our floating state matches that before saying we're zoomed.

This fixes calling zoom:nil on a borderless resizable window that was created with the same size as the usable desktop area, which happens to also be the maximized state.

Fixes https://github.com/libsdl-org/SDL/issues/12228
2025-02-21 18:38:12 -08:00
Petar Popovic
b5297de56f Add 'const' to pointer parameters 2025-02-21 15:59:40 -08:00
Sam Lantinga
911e53dece Retain mouse focus as long as we're getting mouse events
Fixes https://github.com/libsdl-org/SDL/issues/12218
Fixes https://github.com/libsdl-org/SDL/issues/12323
2025-02-21 15:35:28 -08:00
Sam Lantinga
3b8cb62283 Make it easier to enable IME debug logs 2025-02-21 15:24:45 -08:00
williamhCode
9a607e886e make start&length represent utf32 indices 2025-02-21 12:54:56 -08:00
Anonymous Maarten
9d06145d6c ci: fix type + names of intel compiler artifacts 2025-02-21 21:11:54 +01:00
Timothee "TTimo" Besset
fa380a4004 Update include/SDL3/SDL_assert.h
Co-authored-by: Sam Lantinga <slouken@libsdl.org>
2025-02-21 11:07:54 -08:00
Timothee "TTimo" Besset
2a1b617fb2 Update include/SDL3/SDL_assert.h
Co-authored-by: Sam Lantinga <slouken@libsdl.org>
2025-02-21 11:07:54 -08:00
Timothee 'TTimo' Besset
69e03094bd fallback to defining SDL_TriggerBreakpoint as __builtin_trap in older linux arm64 environments that do not have a __has_builtin facility 2025-02-21 11:07:54 -08:00
Petar Popovic
c70f54e28b Remove redundant casts 2025-02-21 10:09:10 -08:00
Sam Lantinga
2e346d7166 Added 32-bit texture formats to Texture_GetBlockWidth() and Texture_GetBlockHeight()
Fixes https://github.com/libsdl-org/SDL/issues/12335
2025-02-21 09:29:18 -08:00
Sam Lantinga
5d776c070a Refactored SDL_CreateJoystickName() into a general SDL_CreateDeviceName() 2025-02-21 09:10:54 -08:00
expikr
3293eb1a16 use hidapi to get mouse/keyboard string 2025-02-21 07:42:20 -08:00
Anonymous Maarten
7855842306 ci: disable precompiled headers for classic intel compiler 2025-02-21 04:49:33 +01:00
Anonymous Maarten
71d1de5d96 ci: add cppflags to CMAKE_(C|CXX)_FLAGS 2025-02-21 04:46:26 +01:00
Anonymous Maarten
28f0867948 SPA_FALLTHROUGH expands to nothing when using the Intel compiler 2025-02-21 04:30:19 +01:00
Anonymous Maarten
8d3db06ff2 ci: GitHub is retiring Ubuntu 20.04 support 2025-02-21 04:30:19 +01:00
Anonymous Maarten
c153f83df0 ci: enable ccache 2025-02-21 04:30:19 +01:00
SDL Wiki Bot
52ee0c1058 Sync SDL3 wiki -> header
[ci skip]
2025-02-20 20:17:22 +00:00
Sam Lantinga
9267930fea Added a fast path for converting the same format and pitch 2025-02-20 12:16:26 -08:00
Sam Lantinga
f24f9d3bed Revert "testcamera: added support for Motion JPEG camera frames"
This reverts commit 5ccee77190.
2025-02-20 12:16:26 -08:00
Sam Lantinga
2e89c53ebc Added support for decoding MJPG into NV12 textures 2025-02-20 12:16:26 -08:00
Sam Lantinga
06602f4e80 Document that the pitch is the length of the image data for SDL_PIXELFORMAT_MJPG 2025-02-20 12:16:26 -08:00
Sam Lantinga
a792434a37 Added initial MJPG support using stb_image 2025-02-20 12:16:26 -08:00
Anonymous Maarten
baf69edfc7 Revert "cmake: build SDL_uclibc with -fPIC"
This reverts commit 9784414ddd.

Some platforms (e.g. ps2) do not support pic.
2025-02-20 20:37:53 +01:00
Anonymous Maarten
fdf8e5a704 ci: build static loongarch libraries with -fPIC 2025-02-20 20:28:57 +01:00
Anonymous Maarten
9784414ddd cmake: build SDL_uclibc with -fPIC 2025-02-20 20:28:54 +01:00
Frank Praznik
b48de48efb wayland: Add support for high-DPI icons 2025-02-20 13:57:37 -05:00
Frank Praznik
6e0264d38e x11: Use the current or last-requested window position when setting the size hint
The move operation is just a no-op to try and force the hint to take effect, so it should use the current window coordinates.
2025-02-20 13:25:47 -05:00
Sam Lantinga
1a38960eee Call SDL_DiscardAllCommands() for the software renderer as well 2025-02-20 09:53:11 -08:00
Sam Lantinga
8f4c5e15f1 Finish any drawing when destroying a software renderer
Fixes the SDL3 version of https://github.com/libsdl-org/sdl2-compat/issues/373
2025-02-20 08:49:47 -08:00
Paper
1a853973ab thread/windows: fix stack overflow in exception naming 2025-02-20 07:57:00 -08:00
Sam Clegg
a40b2de946 Fix SDL_emscriptenaudio.c under wasm64
Same as #12332 which already landed on SDL2 branch.
2025-02-19 13:00:47 -08:00
Anonymous Maarten
523e6530a8 SDL_test: fix "'function': different 'const' qualifiers" warning in SDL_test_harness 2025-02-19 19:06:48 +01:00
Frank Praznik
9e4c657ed8 wayland: Fix color manager protocol string check 2025-02-19 11:43:53 -05:00
nightmareci
7500a758b8 Remove usages of restrict keyword in SDL_render.c
I ran into the usage of `restrict` breaking builds targeting Windows XP, as the v141 MSVC toolset doesn't support the keyword.
2025-02-18 11:40:43 -08:00
Frank Praznik
a7f01cd73c x11: Set the pending window position immediately after mapping
Waiting until the first configure event to perform the move can result in the window visibly jumping in position.
2025-02-18 11:27:03 -05:00
Mike Kosek
1fd626939f Renamed DreamPort to DreamPicoPort 2025-02-18 11:06:28 -05:00
ImThour
31f9cb4806 Unchecked Return Value in WIN_SuspendScreenSaver (#12316) 2025-02-17 15:36:56 -08:00
ImThour
057c3602e9 Removing Double-free Issue 2025-02-17 15:34:18 -08:00
ImThour
5c79f4cae1 Incorrect bfOffBits Calculation in WIN_ConvertDIBtoBMP 2025-02-17 13:59:03 -08:00
Cameron Gutman
70d23b2349 README-migration: Remove errant reference to SDL_FALSE_ 2025-02-17 15:16:35 -06:00
Petar Popovic
6aef6ae9a8 AddPulseAudioDevice(): Fix use-after-free 2025-02-17 11:12:44 -08:00
Frank Praznik
3b4cfc11f0 wayland: Update copyright dates in added color manager source files 2025-02-17 11:36:00 -05:00
Frank Praznik
fadb261b66 wayland: Add color manager protocol support
Support the official wp_color_manager_v1 protocol.
2025-02-17 11:31:12 -05:00
Sam Lantinga
6ef687c864 Simplified and fixed media foundation buffer handling 2025-02-17 08:14:30 -08:00
Sam Lantinga
de12cb92dc Fixed crash at shutdown with new hashtable code 2025-02-17 08:14:30 -08:00
ImThour
a513168902 Fixed Memory/Resource Leaks (#12304) 2025-02-17 07:30:30 -08:00
Petar Popovic
045a4492f1 test/testaudio.c: Fix use-after-free warning 2025-02-16 19:35:54 -08:00
Petar Popovic
da2460f9e7 test/testautomation_audio.c: Free variables before returning 2025-02-16 16:57:56 -08:00
captain0xff
7ea0ffb748 update 2025-02-16 13:44:00 -08:00
captain0xff
06eb10c518 haiku: check if the returned _SDL_GLView is null or not 2025-02-16 13:44:00 -08:00
SDL Wiki Bot
dea99e54fd Sync SDL3 wiki -> header
[ci skip]
2025-02-16 17:44:58 +00:00
Sam Lantinga
1754943596 Fixed camera frame acquisition on Windows 7
Fixes https://github.com/libsdl-org/SDL/issues/12210
2025-02-16 08:13:35 -08:00
Sam Lantinga
e3d9f1172c Remove the reference to the thread when it is detached
Fixes https://github.com/libsdl-org/SDL/issues/12301
2025-02-16 07:56:30 -08:00
Petar Popovic
831fc70923 test/testautomation_intrinsics.c: Free variables before returning 2025-02-16 07:50:07 -08:00
Petar Popovic
c6a3b5b6ef src/test/SDL_test_harness.c: Free variables before returning 2025-02-15 21:00:04 -08:00
Ryan C. Gordon
84a236c92e hashtable: Redesign the hashtable API.
This was intended to make the API public, so SDL_hashtable.h got an extreme
documentation makeover, but for now this remains a private header.

This makes several significant interface changes to SDL_HashTable, and
improves code that makes use of it in various ways.

- The ability to make "stackable" tables is removed. Apparently this still
  worked with the current implementation, but I could see a future
  implementation struggle mightily to support this. It'll be better for
  something external to build on top of the table if it needs it, inserting a
  linked list of stacked items as the hash values and managing them separately.
  There was only one place in SDL using this, unnecessarily, and that has also
  been cleaned up to not need it.
- You no longer specify "buckets" when creating a table, but rather an
  estimated number of items the table is meant to hold. The bucket count was
  crucial to our classic hashtable implementation, but meant less once we
  moved to an Open Addressing implementation anyhow, since the bucket count
  isn't static (and they aren't really "buckets" anymore either). Now you
  can just report how many items you think the hash will hold and SDL will
  allocate a reasonable default for you...or 0 to not guess, and SDL will
  start small and grow as necessary, which is often the correct thing to do.
- There's no more SDL_IterateHashTableKey because there's no more "stackable"
  hash tables.
- SDL_IterateHashTable() now uses a callback, which matches other parts of SDL,
  and also lets us hold the read-lock for the entire iteration and get rid of
  the goofy iterator state variable.
- SDL_InsertIntoHashTable() now lets you specify whether to replace existing
  keys or fail if the key already exists.
- Callbacks now use SDL conventions (userdata as the first param).
- Other naming convention fixes.

I discovered we use a lot of hash tables in SDL3 internally. :) So the bulk
of this work is fixing up that code to use the new interfaces, and simplifying
things (like checking for an item to remove it if it already exists before
inserting a replacement...just do the insert atomically, it'll do all that
for you!).
2025-02-15 18:52:56 -05:00
Cameron Gutman
4a9b579195 joystick: remove dead udev code
SDL_USE_LIBUDEV is never even defined here and SDL_hid_init() already does this.
2025-02-15 14:17:13 -06:00
SDL Wiki Bot
ba45256940 Sync SDL3 wiki -> header
[ci skip]
2025-02-15 17:42:27 +00:00
Sam Lantinga
fd4e6d2949 Don't render 0 sized texture rectangles
Fixes https://github.com/libsdl-org/sdl2-compat/issues/355
2025-02-15 07:07:56 -08:00
Frank Praznik
6f3b14a6df audio/video: Fix uninitialized field warnings 2025-02-14 17:16:10 -05:00
Sam Lantinga
5b98c4a524 Fixed motion events with TOOL_TYPE_UNKNOWN
This happens using hand tracking on a VR headset, and should be treated like normal touch interaction.
2025-02-14 11:50:43 -08:00
Chen Steenvoorden
8a648dfd9b emscripten: Fixed unregistering of key event handlers 2025-02-14 10:15:15 -08:00
Petar Popovic
c16b7bcb7a SDL_Get*Driver() functions: Set error message on failure 2025-02-13 16:10:37 -08:00
ImThour
ed0a03e9b5 Fixed Cursor Icon State for SYSTEM_CURSOR_PROGRESS 2025-02-13 11:38:41 -08:00
Petar Popovic
5dce8c748f SDL_GetRelativeMouseState(): Get relative mouse position also when relative mouse mode is disabled 2025-02-13 11:34:24 -08:00
SDL Wiki Bot
cedf53bbc2 Sync SDL3 wiki -> header
[ci skip]
2025-02-13 05:39:38 +00:00
Sam Lantinga
3de975884a Document the "trace" log priority 2025-02-12 21:37:30 -08:00
Sam Lantinga
b9d018f2a2 Fixed wayland cursor use-after-free at shutdown 2025-02-12 20:47:31 -08:00
SDL Wiki Bot
041894a523 Sync SDL3 wiki -> header
[ci skip]
2025-02-13 01:45:34 +00:00
Semphris
3be67ced64 Fix GTK tray icon without menu + lifetime 2025-02-12 16:18:31 -08:00
Ryan C. Gordon
1354affd28 haiku: Fixed keyboard input.
_GetWinID() doesn't work with keyboard-related BMessages, because Haiku
assumes you know what window has keyboard focus at the time, so these events
don't have a `window-id` property. So when this call failed, the key event
handler would return early.

This was probably a copy/paste error that snuck in at some point, as SDL2
doesn't have this issue.
2025-02-12 17:17:14 -05:00
Sam Lantinga
d2b7a84651 Fixed SDL_GetNumGamepadTouchpads() returning 1 for a NULL gamepad 2025-02-12 13:08:41 -08:00
Sam Lantinga
ca29304ce1 Fixed continually resetting keyboard and mouse readings 2025-02-12 13:02:15 -08:00
Sam Lantinga
f67c644649 Fixed reporting hat positions for GameInput controllers 2025-02-12 13:02:15 -08:00
Sam Lantinga
1b35ca9c32 Refactored GameInput initialization 2025-02-12 13:02:15 -08:00
Frank Praznik
706de78a9e audio/video: Skip preferred drivers when loading a driver on demand
Preferred driver entries have special conditions for initializing, which aren't relevant when a specific driver was explicitly requested.
2025-02-12 11:51:36 -05:00
Sam Lantinga
715c18739b Added an internal hint "SDL_VIDEO_X11_XINPUT2" for sdl2-compat 2025-02-11 15:11:33 -08:00
Sam Lantinga
ce69e98989 Copy SDL2_SYSWMEVENT data into temporary memory for the event 2025-02-11 15:11:33 -08:00
coffeechriph
55fd205ba4 Add missing integer texture formats to SDL_GPUTextureFormatTexelBlockSize (#12151) 2025-02-11 14:21:30 -08:00
Semphris
e6029401d9 Check for non-NULL icon for trays on Unix 2025-02-11 13:47:17 -08:00
captain0xff
b03332b68d updated bytepusher demo to be C++ compatible 2025-02-11 13:38:29 -08:00
captain0xff
5dd2492645 updated the snake demo to be C++ compatible 2025-02-11 13:38:29 -08:00
Frank Praznik
78f816d74e x11: Apply the modifier state from key events
Use the modifier state supplied with key events to track the system modifier state instead of relying on the state returned by XQueryPointer(), which can be racy when used with automated text entry.
2025-02-11 14:14:12 -05:00
Sam Lantinga
99cf16287a Fixed the name of SDL_SYSWMEVENT 2025-02-11 09:48:40 -08:00
Sam Lantinga
6c37971521 Removed the mapping for the Sanwa Supply JY-P76USV
It turns out the mapping we include doesn't work for real controllers, and they're using a generic chipset and generic name and can't be generally distinguished from other controllers.

See https://github.com/libsdl-org/SDL/issues/8644 for details.
2025-02-11 07:59:25 -08:00
Edu Garcia
9b18e8438f [GPU] D3D12 backend debug markers were being cut
Code used wcslen that return number of characters, but D3D12 debug layer uses bytes + wide chars
2025-02-11 07:21:44 -08:00
Sam Lantinga
0bce19cf15 The 10-bit texture formats have alpha on Direct3D
A similar change was made for Vulkan in a036aeda3b
2025-02-10 19:45:02 -08:00
Sam Lantinga
3cfa476d3f Added support for SDL_PIXELFORMAT_ABGR8888 textures
This is the output format of stb_image for image decoding, so let's avoid a texture format conversion where possible.

Also standardized SDL_PIXELFORMAT_ARGB8888 as the default texture format for all renderers.
2025-02-10 19:45:02 -08:00
Sam Lantinga
5ccee77190 testcamera: added support for Motion JPEG camera frames 2025-02-10 17:18:16 -08:00
Sam Lantinga
cf41ccc6ce Removed stb_image.h from SDL
This adds quite a bit of code size to SDL for a niche use-case. This is easily handled in the application instead.
2025-02-10 17:18:16 -08:00
Sam Lantinga
9308404e9a Removed functions not used by SDL 2025-02-10 17:18:16 -08:00
Sam Lantinga
5e31bbf05e Remove functions not used when STBI_NO_PNG and STBI_NO_HDR are defined 2025-02-10 17:18:16 -08:00
Sam Lantinga
84b0c13c44 Added support for Motion JPEG camera capture
Fixes https://github.com/libsdl-org/SDL/issues/12183
2025-02-10 17:18:16 -08:00
Frank Praznik
3bc53b9ade wayland: Don't set libdecor frame visibility before the first commit
This will be needed later, after libdecor passes through toplevel bounds, but for now it causes a crash in the Cairo plugin, so remove it.
2025-02-10 18:39:36 -05:00
Frank Praznik
c032586262 wayland: Scale-to-display mode requires both viewports and xdg-output for proper functionality 2025-02-10 15:47:28 -05:00
SDL Wiki Bot
b63d3afc18 Sync SDL3 wiki -> header
[ci skip]
2025-02-10 20:15:51 +00:00
Sam Lantinga
0bc1f87120 Added SDL_PROP_SURFACE_HOTSPOT_X_NUMBER and SDL_PROP_SURFACE_HOTSPOT_Y_NUMBER 2025-02-10 12:15:03 -08:00
Frank Praznik
da464e9e5f win32: Keep the window on the last maximized display when leaving fullscreen
A window may have been maximized by dragging it to the top of another display, in which case the floating position may be out-of-date. If the window is being restored to maximized, and the maximized and floating position are on different displays, try to center the window on the maximized display for restoration, which mimics native Windows behavior.
2025-02-10 15:05:54 -05:00
Mike Kosek
bf01cc8ce7 Renamed "Dreamcast Controller Usb" to "DreamPort" 2025-02-10 10:33:47 -08:00
Sam Lantinga
ecd089bb69 Don't return short waits from SDL_IOReady()
The Wayland keyboard repeat code assumes that if we have a certain timeout then we'll wait at least that long, and generate a key repeat event on timeout. If we wait a shorter time, we won't generate a key repeat event and then return 0, even if we were supposed to wait indefinitely.

Fixes https://github.com/libsdl-org/SDL/issues/12239
2025-02-10 10:29:30 -08:00
danginsburg
4fd0b2a85c Fix #12142 - the problem was if the size of the vertex buffer was exceeded, the currentVertexBuffer would be reset to zero and thus we'd leave it pointing to an in-use VB that would get overwritten on the next present before the vkQueueSubmit occurred. 2025-02-10 08:47:57 -08:00
Sam Lantinga
f6126e9ea1 Centered joystick axis values should be 0
Fixes https://github.com/libsdl-org/sdl2-compat/issues/338
2025-02-10 08:36:00 -08:00
Neal Gompa
d35bef64e9 pipewire: Ensure that the correct struct is used for enumeration APIs
PipeWire now requires the correct struct type is used, otherwise
it will fail to compile.

Reference: 188d920733

Fixes: https://github.com/libsdl-org/SDL/issues/12224
2025-02-10 11:03:01 -05:00
rubisetcie
9bd6d36471 Added SDL_DEPS_SHARED option to control default dynamic loading of shared libraries (#12215) 2025-02-10 07:40:24 -08:00
Stenzek
78721d720c joystick: Fix PS5 player LED hint change callback name
The LED hint was getting registered for SDL_HINT_JOYSTICK_ENHANCED_REPORTS
instead of SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, which results in a
use-after-free followed by a crash.
2025-02-10 07:36:07 -08:00
ImThour
7aba6c4c73 Proper Resource Cleanup in WIN_UpdateWindowShape
mask is created but never deleted if SetWindowRgn() fails. This may lead to resource leaks.
2025-02-09 16:11:53 -08:00
Christian Walter
e29ebb9f18 Update geometry renderer example
This PR updates the geometry renderer example such that the `color` values of `vertices[3]` are set correctly in `SDL_AppIterate`.
2025-02-09 10:53:14 -08:00
ImThour
ca9a044b3e Memory Leak in WIN_CreateHCursor When CreateColorBitmap Fails 2025-02-09 10:49:56 -08:00
Clint Kilmer
69d28027ad Fix for 500ms hang after user clicks on the title bar, but before moving (#12217)
Reference: https://gamedev.net/forums/topic/672094-keeping-things-moving-during-win32-moveresize-events/5254386/
2025-02-08 11:21:10 -08:00
Guldoman
a0b6c0fd8f x11: Don't wait for events when the connection errored out (#8392)
Calling `X11_XIfEvent` after the X11 connection errored out can result in hangs.
2025-02-08 10:07:11 -08:00
Mike Kosek
864bb65ce9 Removed crc 2025-02-08 07:56:40 -08:00
Mike Kosek
006605c3bf Corrected alphabetical order 2025-02-08 07:56:40 -08:00
Mike Kosek
dc035c5ca6 Added mapping for Dreamcast Controller USB 2025-02-08 07:56:40 -08:00
Michael Savage
5d1bbd9b27 Fix SSE 4.2 test
When building with zig cc I get:

```
error: always_inline function '_mm_crc32_u32' requires target feature 'crc32', but would be inlined into function 'calc_crc32c' that is compiled without support for 'crc32'
    5 |       crc32c = (unsigned)_mm_crc32_u32(crc32c, *(unsigned*)text);
      |                          ^
1 error generated.
```

This PR adds -mcrc32, another option would be to use a different SSE4.2 op
2025-02-08 07:37:14 -08:00
ds-sloth
7c12c63f63 Add generic SDL_syscond to N3DS threads source list 2025-02-06 18:02:03 -08:00
ds-sloth
2ced6b09fc Delete src/thread/n3ds/SDL_syscond.c
This PR removes the incorrect implementation of `SDL_cond` currently included with the 3DS port.

Pseudocode of the incorrect implementation of `SDL_CondWait` this PR removes:

* Receive an `SDL_cond` backed by a `libctru` `CondVar` and an `SDL_mutex` backed by a `libctru` `RecursiveLock`.
* Want to call `libctru` function `CondVar_Wait` which expects a `CondVar` and a `LightLock` (non-recursive lock)
* Do so by calling this function with the internal (inadequately protected) `LightLock` member of the `RecursiveLock` (`&mutex->lock.lock` on line 105), without updating any internal thread or lock count fields of the `RecursiveLock`.

Happy to discuss or test some examples. My own use case works much better with the generic cond logic, and this seems like a safe fix to me given that the generic logic is well-tested and this seems not to be.

If you like the PR I'll send another one for the SDL2 branch.
2025-02-06 18:02:03 -08:00
SDL Wiki Bot
7af17f874c Sync SDL3 wiki -> header
[ci skip]
2025-02-07 02:00:45 +00:00
Sam Lantinga
982094c85c Updated to version 3.2.5 for development 2025-02-06 16:40:59 -08:00
356 changed files with 21147 additions and 5258 deletions

View File

@@ -20,7 +20,6 @@ class AppleArch(Enum):
class MsvcArch(Enum):
X86 = "x86"
X64 = "x64"
Arm32 = "arm"
Arm64 = "arm64"
@@ -28,7 +27,6 @@ class JobOs(Enum):
WindowsLatest = "windows-latest"
UbuntuLatest = "ubuntu-latest"
MacosLatest = "macos-latest"
Ubuntu20_04 = "ubuntu-20.04"
Ubuntu22_04 = "ubuntu-22.04"
Ubuntu24_04 = "ubuntu-24.04"
Ubuntu24_04_arm = "ubuntu-24.04-arm"
@@ -55,12 +53,12 @@ class SdlPlatform(Enum):
Riscos = "riscos"
FreeBSD = "freebsd"
NetBSD = "netbsd"
OpenBSD = "openbsd"
class Msys2Platform(Enum):
Mingw32 = "mingw32"
Mingw64 = "mingw64"
Clang32 = "clang32"
Clang64 = "clang64"
Ucrt64 = "ucrt64"
@@ -104,22 +102,19 @@ class JobSpec:
JOB_SPECS = {
"msys2-mingw32": JobSpec(name="Windows (msys2, mingw32)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw32", msys2_platform=Msys2Platform.Mingw32, ),
"msys2-mingw64": JobSpec(name="Windows (msys2, mingw64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw64", msys2_platform=Msys2Platform.Mingw64, ),
"msys2-clang32": JobSpec(name="Windows (msys2, clang32)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw32-clang", msys2_platform=Msys2Platform.Clang32, ),
"msys2-clang64": JobSpec(name="Windows (msys2, clang64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw64-clang", msys2_platform=Msys2Platform.Clang64, ),
"msys2-ucrt64": JobSpec(name="Windows (msys2, ucrt64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msys2, artifact="SDL-mingw64-ucrt", msys2_platform=Msys2Platform.Ucrt64, ),
"msvc-x64": JobSpec(name="Windows (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x64", msvc_arch=MsvcArch.X64, msvc_project="VisualC/SDL.sln", ),
"msvc-x86": JobSpec(name="Windows (MSVC, x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x86", msvc_arch=MsvcArch.X86, msvc_project="VisualC/SDL.sln", ),
"msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x64", msvc_arch=MsvcArch.X64, clang_cl=True, ),
"msvc-clang-x86": JobSpec(name="Windows (MSVC, clang-cl x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x86", msvc_arch=MsvcArch.X86, clang_cl=True, ),
"msvc-arm32": JobSpec(name="Windows (MSVC, ARM)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm32", msvc_arch=MsvcArch.Arm32, ),
"msvc-arm64": JobSpec(name="Windows (MSVC, ARM64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm64", msvc_arch=MsvcArch.Arm64, ),
"msvc-gdk-x64": JobSpec(name="GDK (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-GDK", msvc_arch=MsvcArch.X64, msvc_project="VisualC-GDK/SDL.sln", gdk=True, no_cmake=True, ),
"ubuntu-20.04": JobSpec(name="Ubuntu 20.04", os=JobOs.Ubuntu20_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu20.04", ),
"ubuntu-22.04": JobSpec(name="Ubuntu 22.04", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04", ),
"ubuntu-24.04-arm64": JobSpec(name="Ubuntu 24.04 (ARM64)", os=JobOs.Ubuntu24_04_arm, platform=SdlPlatform.Linux, artifact="SDL-ubuntu24.04-arm64", ),
"steamrt-sniper": JobSpec(name="Steam Linux Runtime (Sniper)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Linux, artifact="SDL-slrsniper", container="registry.gitlab.steamos.cloud/steamrt/sniper/sdk:beta", ),
"ubuntu-intel-icx": JobSpec(name="Ubuntu 20.04 (Intel oneAPI)", os=JobOs.Ubuntu20_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu20.04-oneapi", intel=IntelCompiler.Icx, ),
"ubuntu-intel-icc": JobSpec(name="Ubuntu 20.04 (Intel Compiler)", os=JobOs.Ubuntu20_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu20.04-icc", intel=IntelCompiler.Icc, ),
"ubuntu-intel-icx": JobSpec(name="Ubuntu 22.04 (Intel oneAPI)", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04-oneapi", intel=IntelCompiler.Icx, ),
"ubuntu-intel-icc": JobSpec(name="Ubuntu 22.04 (Intel Compiler)", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04-icc", intel=IntelCompiler.Icc, ),
"macos-framework-x64": JobSpec(name="MacOS (Framework) (x64)", os=JobOs.Macos13, platform=SdlPlatform.MacOS, artifact="SDL-macos-framework", apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, xcode=True, ),
"macos-framework-arm64": JobSpec(name="MacOS (Framework) (arm64)", os=JobOs.MacosLatest, platform=SdlPlatform.MacOS, artifact=None, apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, ),
"macos-gnu-arm64": JobSpec(name="MacOS (GNU prefix)", os=JobOs.MacosLatest, platform=SdlPlatform.MacOS, artifact="SDL-macos-arm64-gnu", apple_framework=False, apple_archs={AppleArch.Aarch64, }, ),
@@ -141,6 +136,7 @@ JOB_SPECS = {
"vita-pvr": JobSpec(name="Sony PlayStation Vita (GLES w/ PVR_PSP2)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Vita, artifact="SDL-vita-pvr", container="vitasdk/vitasdk:latest", vita_gles=VitaGLES.Pvr, ),
"riscos": JobSpec(name="RISC OS", os=JobOs.UbuntuLatest, platform=SdlPlatform.Riscos, artifact="SDL-riscos", container="riscosdotinfo/riscos-gccsdk-4.7:latest", ),
"netbsd": JobSpec(name="NetBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.NetBSD, artifact="SDL-netbsd-x64", ),
"openbsd": JobSpec(name="OpenBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.OpenBSD, artifact="SDL-openbsd-x64", ),
"freebsd": JobSpec(name="FreeBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.FreeBSD, artifact="SDL-freebsd-x64", ),
}
@@ -166,6 +162,7 @@ class JobDetails:
platform: str
artifact: str
no_cmake: bool
ccache: bool = False
build_tests: bool = True
container: str = ""
cmake_build_type: str = "RelWithDebInfo"
@@ -177,6 +174,7 @@ class JobDetails:
brew_packages: list[str] = dataclasses.field(default_factory=list)
cmake_toolchain_file: str = ""
cmake_arguments: list[str] = dataclasses.field(default_factory=list)
cmake_generator: str = "Ninja"
cmake_build_arguments: list[str] = dataclasses.field(default_factory=list)
clang_tidy: bool = True
cppflags: list[str] = dataclasses.field(default_factory=list)
@@ -225,12 +223,14 @@ class JobDetails:
check_sources: bool = False
setup_python: bool = False
pypi_packages: list[str] = dataclasses.field(default_factory=list)
binutils_strings: str = "strings"
def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]:
data = {
"name": self.name,
"key": self.key,
"os": self.os,
"ccache": self.ccache,
"container": self.container if self.container else "",
"platform": self.platform,
"artifact": self.artifact,
@@ -257,6 +257,7 @@ class JobDetails:
"cflags": my_shlex_join(self.cppflags + self.cflags),
"cxxflags": my_shlex_join(self.cppflags + self.cxxflags),
"ldflags": my_shlex_join(self.ldflags),
"cmake-generator": self.cmake_generator,
"cmake-toolchain-file": self.cmake_toolchain_file,
"clang-tidy": self.clang_tidy,
"cmake-arguments": my_shlex_join(self.cmake_arguments),
@@ -291,6 +292,7 @@ class JobDetails:
"check-sources": self.check_sources,
"setup-python": self.setup_python,
"pypi-packages": my_shlex_join(self.pypi_packages),
"binutils-strings": self.binutils_strings,
}
return {k: v for k, v in data.items() if v != ""}
@@ -343,7 +345,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
case IntelCompiler.Icc:
job.cc = "icc"
job.cxx = "icpc"
# Disable deprecation warning
job.cppflags.append("-diag-disable=10441")
# Avoid 'Catastrophic error: cannot open precompiled header file'
job.cmake_arguments.append("-DCMAKE_DISABLE_PRECOMPILE_HEADERS:BOOL=ON")
job.clang_tidy = False
case _:
raise ValueError(f"Invalid intel={spec.intel}")
@@ -402,10 +407,6 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.msvc_vcvars_arch = "x64_x86"
case MsvcArch.X64:
job.msvc_vcvars_arch = "x64"
case MsvcArch.Arm32:
job.msvc_vcvars_arch = "x64_arm"
job.msvc_vcvars_sdk = "10.0.22621.0" # 10.0.26100.0 dropped ARM32 um and ucrt libraries
job.run_tests = False
case MsvcArch.Arm64:
job.msvc_vcvars_arch = "x64_arm64"
job.run_tests = False
@@ -421,6 +422,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
if spec.name.startswith("Ubuntu"):
assert spec.os.value.startswith("ubuntu-")
job.apt_packages.extend((
"ccache",
"gnome-desktop-testing",
"libasound2-dev",
"libpulse-dev",
@@ -454,6 +456,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.apt_packages.extend((
"libunwind-dev", # For SDL_test memory tracking
))
job.ccache = True
if trackmem_symbol_names:
# older libunwind is slow
job.cmake_arguments.append("-DSDLTEST_TIMEOUT_MULTIPLIER=2")
@@ -462,8 +465,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
fpic = True
case SdlPlatform.Ios | SdlPlatform.Tvos:
job.brew_packages.extend([
"ccache",
"ninja",
])
job.ccache = True
job.clang_tidy = False
job.run_tests = False
job.test_pkg_config = False
@@ -506,8 +511,15 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
))
job.shared_lib = SharedLibType.DYLIB
job.static_lib = StaticLibType.A
job.ccache = True
if spec.os == JobOs.Macos13:
job.ccache = False
job.apt_packages = []
job.brew_packages.append("ninja")
job.brew_packages.extend((
"ninja",
))
if job.ccache:
job.brew_packages.append("ccache")
if job.clang_tidy:
job.brew_packages.append("llvm")
if spec.xcode:
@@ -515,6 +527,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
case SdlPlatform.Android:
job.android_gradle = spec.android_gradle
job.android_mk = spec.android_mk
job.apt_packages.append("ccache")
job.run_tests = False
job.shared_lib = SharedLibType.SO
job.static_lib = StaticLibType.A
@@ -525,6 +538,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
if spec.android_mk or spec.android_gradle:
job.apt_packages = []
if not spec.no_cmake:
job.ccache = True
job.cmake_arguments.extend((
f"-DANDROID_PLATFORM={spec.android_platform}",
f"-DANDROID_ABI={spec.android_abi}",
@@ -539,9 +553,15 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
"testmultiaudio-apk",
"testsprite-apk",
]
# -fPIC is required after updating NDK from 21 to 28
job.cflags.append("-fPIC")
job.cxxflags.append("-fPIC")
case SdlPlatform.Emscripten:
job.clang_tidy = False # clang-tidy does not understand -gsource-map
job.shared = False
job.ccache = True
job.apt_packages.append("ccache")
job.cmake_config_emulator = "emcmake"
job.cmake_build_type = "Debug"
job.test_pkg_config = False
@@ -567,11 +587,12 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.setup_python = True
job.pypi_packages.append("selenium")
case SdlPlatform.Ps2:
job.ccache = False # actions/ccache does not work in psp container (incompatible tar of busybox)
build_parallel = False
job.shared = False
job.sudo = ""
job.apt_packages = []
job.apk_packages = ["cmake", "gmp", "mpc1", "mpfr4", "ninja", "pkgconf", "git", ]
job.apk_packages = ["ccache", "cmake", "gmp", "mpc1", "mpfr4", "ninja", "pkgconf", "git", ]
job.cmake_toolchain_file = "${PS2DEV}/ps2sdk/ps2dev.cmake"
job.clang_tidy = False
job.run_tests = False
@@ -580,10 +601,11 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.ldflags = ["-L${PS2DEV}/ps2sdk/ee/lib", "-L${PS2DEV}/gsKit/lib", "-L${PS2DEV}/ps2sdk/ports/lib", ]
job.static_lib = StaticLibType.A
case SdlPlatform.Psp:
job.ccache = False # actions/ccache does not work in psp container (incompatible tar of busybox)
build_parallel = False
job.sudo = ""
job.apt_packages = []
job.apk_packages = ["cmake", "gmp", "mpc1", "mpfr4", "ninja", "pkgconf", ]
job.apk_packages = ["ccache", "cmake", "gmp", "mpc1", "mpfr4", "ninja", "pkgconf", ]
job.cmake_toolchain_file = "${PSPDEV}/psp/share/pspdev.cmake"
job.clang_tidy = False
job.run_tests = False
@@ -593,9 +615,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.pollute_directories = ["${PSPDEV}/include", "${PSPDEV}/psp/include", "${PSPDEV}/psp/sdk/include", ]
job.static_lib = StaticLibType.A
case SdlPlatform.Vita:
job.ccache = True
job.sudo = ""
job.apt_packages = []
job.apk_packages = ["cmake", "ninja", "pkgconf", "bash", "tar"]
job.apk_packages = ["ccache", "cmake", "ninja", "pkgconf", "bash", "tar"]
job.cmake_toolchain_file = "${VITASDK}/share/vita.toolchain.cmake"
assert spec.vita_gles is not None
job.setup_vita_gles_type = {
@@ -616,8 +639,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.cc = "arm-vita-eabi-gcc"
job.static_lib = StaticLibType.A
case SdlPlatform.Haiku:
job.ccache = True
fpic = False
job.run_tests = False
job.apt_packages.append("ccache")
job.cc = "x86_64-unknown-haiku-gcc"
job.cxx = "x86_64-unknown-haiku-g++"
job.sudo = ""
@@ -629,19 +654,23 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.shared_lib = SharedLibType.SO_0
job.static_lib = StaticLibType.A
case SdlPlatform.PowerPC64 | SdlPlatform.PowerPC:
job.ccache = True
# FIXME: Enable SDL_WERROR
job.werror = False
job.clang_tidy = False
job.run_tests = False
job.sudo = ""
job.apt_packages = []
job.apt_packages = ["ccache"]
job.shared_lib = SharedLibType.SO_0
job.static_lib = StaticLibType.A
job.cmake_arguments.extend((
"-DSDL_UNIX_CONSOLE_BUILD=ON",
))
case SdlPlatform.LoongArch64:
job.ccache = True
fpic = True
job.run_tests = False
job.apt_packages.append("ccache")
job.cc = "${LOONGARCH64_CC}"
job.cxx = "${LOONGARCH64_CXX}"
job.cmake_arguments.extend((
@@ -653,31 +682,36 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.shared_lib = SharedLibType.SO_0
job.static_lib = StaticLibType.A
case SdlPlatform.N3ds:
job.cmake_generator = "Unix Makefiles"
job.cmake_build_arguments.append("-j$(nproc)")
job.ccache = False
job.shared = False
job.apt_packages = ["ninja-build", "binutils"]
job.apt_packages = []
job.clang_tidy = False
job.run_tests = False
job.cc_from_cmake = True
job.cmake_toolchain_file = "${DEVKITPRO}/cmake/3DS.cmake"
job.binutils_strings = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-strings"
job.static_lib = StaticLibType.A
case SdlPlatform.Msys2:
job.ccache = True
job.shell = "msys2 {0}"
assert spec.msys2_platform
job.msys2_msystem = spec.msys2_platform.value
job.msys2_env = {
"mingw32": "mingw-w64-i686",
"mingw64": "mingw-w64-x86_64",
"clang32": "mingw-w64-clang-i686",
"clang64": "mingw-w64-clang-x86_64",
"ucrt64": "mingw-w64-ucrt-x86_64",
}[spec.msys2_platform.value]
job.msys2_no_perl = spec.msys2_platform in (Msys2Platform.Mingw32, Msys2Platform.Clang32)
job.msys2_no_perl = spec.msys2_platform in (Msys2Platform.Mingw32, )
job.shared_lib = SharedLibType.WIN32
job.static_lib = StaticLibType.A
case SdlPlatform.Riscos:
job.ccache = False # FIXME: enable when container gets upgrade
# FIXME: Enable SDL_WERROR
job.werror = False
job.apt_packages = ["cmake", "ninja-build"]
job.apt_packages = ["ccache", "cmake", "ninja-build"]
job.test_pkg_config = False
job.shared = False
job.run_tests = False
@@ -689,7 +723,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
))
job.cmake_toolchain_file = "/home/riscos/env/toolchain-riscos.cmake"
job.static_lib = StaticLibType.A
case SdlPlatform.FreeBSD | SdlPlatform.NetBSD:
case SdlPlatform.FreeBSD | SdlPlatform.NetBSD | SdlPlatform.OpenBSD:
job.cpactions = True
job.no_cmake = True
job.run_tests = False
@@ -713,6 +747,12 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.cpactions_arch = "x86-64"
job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
case SdlPlatform.OpenBSD:
job.cpactions_os = "openbsd"
job.cpactions_version = "7.4"
job.cpactions_arch = "x86-64"
job.cpactions_setup_cmd = "sudo pkg_add -u"
job.cpactions_install_cmd = "sudo pkg_add cmake ninja pkgconf wayland wayland-protocols xwayland libxkbcommon libinotify pulseaudio dbus ibus"
case _:
raise ValueError(f"Unsupported platform={spec.platform}")
@@ -720,12 +760,17 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.check_sources = True
job.setup_python = True
if job.ccache:
job.cmake_arguments.extend((
"-DCMAKE_C_COMPILER_LAUNCHER=ccache",
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
))
if not build_parallel:
job.cmake_build_arguments.append("-j1")
if job.cflags:
job.cmake_arguments.append(f"-DCMAKE_C_FLAGS=\"{my_shlex_join(job.cflags)}\"")
if job.cxxflags:
job.cmake_arguments.append(f"-DCMAKE_CXX_FLAGS=\"{my_shlex_join(job.cxxflags)}\"")
if job.cflags or job.cppflags:
job.cmake_arguments.append(f"-DCMAKE_C_FLAGS=\"{my_shlex_join(job.cflags + job.cppflags)}\"")
if job.cxxflags or job.cppflags:
job.cmake_arguments.append(f"-DCMAKE_CXX_FLAGS=\"{my_shlex_join(job.cxxflags + job.cppflags)}\"")
if job.ldflags:
job.cmake_arguments.append(f"-DCMAKE_SHARED_LINKER_FLAGS=\"{my_shlex_join(job.ldflags)}\"")
job.cmake_arguments.append(f"-DCMAKE_EXE_LINKER_FLAGS=\"{my_shlex_join(job.ldflags)}\"")

View File

@@ -34,6 +34,7 @@ jobs:
${{ (!matrix.platform.msys2-no-perl && format('{0}-perl', matrix.platform.msys2-env)) || '' }}
${{ matrix.platform.msys2-env }}-pkg-config
${{ matrix.platform.msys2-env }}-clang-tools-extra
${{ (matrix.platform.ccache && format('{0}-ccache', matrix.platform.msys2-env)) || '' }}
- name: 'About this job'
run: |
echo "key=${{ matrix.platform.key }}"
@@ -75,7 +76,7 @@ jobs:
id: setup-ndk
with:
local-cache: true
ndk-version: r21e
ndk-version: r28c
- name: 'Configure Android NDK variables'
if: ${{ matrix.platform.android-ndk }}
shell: sh
@@ -165,12 +166,42 @@ jobs:
done
done
- name: 'Calculate ccache key'
if: ${{ matrix.platform.ccache }}
id: prepare-restore-ccache
run: |
echo "timestamp=$(date -u "+%Y%m%d%H%M_%S")" >> "$GITHUB_OUTPUT"
- name: 'Restore ccache'
if: ${{ matrix.platform.ccache }}
uses: actions/cache/restore@v4
id: restore-ccache
with:
path: ${{ runner.temp }}/ccache
key: ccache-${{ matrix.platform.key }}-${{ steps.prepare-restore-ccache.outputs.timestamp }}
restore-keys: |
ccache-${{matrix.platform.key}}
- name: 'Configure ccache'
if: ${{ matrix.platform.ccache }}
run: |
echo 'CCACHE_DIR=${{ runner.temp }}/ccache' >>${GITHUB_ENV}
- name: 'Prepare ccache'
if: ${{ matrix.platform.ccache && steps.restore-ccache.outputs.cache-hit }}
run: |
if [ "x${{ runner.os }}" = "xmacOS" ]; then
touch_date="2025-02-01T12:00:00Z"
else
touch_date="2025-02-01"
fi
find "${CCACHE_DIR}" -type f -exec touch -a -m -d "$touch_date" {} +
ccache -s
ccache -z
- name: 'Configure (CMake)'
if: ${{ !matrix.platform.no-cmake }}
#shell: ${{ matrix.platform.shell }}
run: |
${{ matrix.platform.source-cmd }}
${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -GNinja \
${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -G "${{ matrix.platform.cmake-generator }}" \
-Wdeprecated -Wdev -Werror \
${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
-DSDL_WERROR=${{ matrix.platform.werror }} \
@@ -201,9 +232,9 @@ jobs:
run: |
echo "This should show us the SDL_REVISION"
echo "Shared library:"
${{ (matrix.platform.shared-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
${{ (matrix.platform.shared-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
echo "Static library:"
${{ (matrix.platform.static-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
${{ (matrix.platform.static-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
- name: 'Run build-time tests (CMake)'
id: tests
if: ${{ !matrix.platform.no-cmake && matrix.platform.run-tests }}
@@ -357,6 +388,17 @@ jobs:
if: ${{ matrix.platform.xcode-sdk != '' }}
run: |
xcodebuild -project Xcode/SDL/SDL.xcodeproj -target SDL3 -configuration Release -sdk ${{ matrix.platform.xcode-sdk }} clean build
- name: 'Prune old ccache files'
if: ${{ matrix.platform.ccache }}
run: |
ccache --evict-older-than=1d
ccache -s
- name: 'Save ccache'
if: ${{ matrix.platform.ccache }}
uses: actions/cache/save@v4
with:
path: ${{ runner.temp }}/ccache
key: ${{ steps.restore-ccache.outputs.cache-primary-key }}
- name: 'Check Sources'
if: ${{ matrix.platform.check-sources }}
run: |
@@ -364,6 +406,14 @@ jobs:
build-scripts/test-versioning.sh
python build-scripts/check_android_jni.py
python build-scripts/check_stdlib_usage.py
- name: 'Verify alignment of Android test apks'
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
run: |
find ./ -iname '*.apk' | xargs -L1 ./build-scripts/check_elf_alignment.sh
- name: 'Verify alignment of Android .so files'
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
run: |
find ./ -iname '*.so' | xargs -L1 ./build-scripts/check_elf_alignment.sh
- name: 'Upload binary package'
uses: actions/upload-artifact@v4
if: ${{ always() && matrix.platform.artifact != '' && (steps.package.outcome == 'success' || steps.cpactions.outcome == 'success') && (matrix.platform.enable-artifacts || steps.tests.outcome == 'failure') }}

View File

@@ -256,7 +256,7 @@ jobs:
msvc:
needs: [src]
runs-on: windows-2019
runs-on: windows-2025
outputs:
VC-x86: ${{ steps.releaser.outputs.VC-x86 }}
VC-x64: ${{ steps.releaser.outputs.VC-x64 }}
@@ -535,7 +535,7 @@ jobs:
uses: nttld/setup-ndk@v1
with:
local-cache: true
ndk-version: r21e
ndk-version: r28c
- name: 'Setup Java JDK'
uses: actions/setup-java@v4
with:

View File

@@ -5,7 +5,7 @@ if(NOT DEFINED CMAKE_BUILD_TYPE)
endif()
# See docs/release_checklist.md
project(SDL3 LANGUAGES C VERSION "3.2.4")
project(SDL3 LANGUAGES C VERSION "3.2.24")
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(SDL3_MAINPROJECT ON)
@@ -79,6 +79,12 @@ include("${SDL3_SOURCE_DIR}/cmake/PreseedEmscriptenCache.cmake")
SDL_DetectCompiler()
SDL_DetectTargetCPUArchitectures(SDL_CPUS)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
list(LENGTH CMAKE_OSX_ARCHITECTURES _num_arches)
if(_num_arches GREATER 1)
set(APPLE_MULTIARCH TRUE)
endif()
endif()
# Increment this if there is an incompatible change - but if that happens,
# we should rename the library from SDL3 to SDL4, at which point this would
@@ -183,26 +189,6 @@ if(MSVC)
set(SDL_RELOCATABLE_DEFAULT ON)
endif()
if(MSVC)
if(NOT SDL_LIBC)
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
endif()
if(MSVC_CLANG)
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
endif()
endif()
set(SDL_SHARED_DEFAULT ON)
set(SDL_STATIC_DEFAULT ON)
@@ -243,6 +229,8 @@ if(SDL_SHARED_DEFAULT AND SDL_STATIC_DEFAULT AND SDL_SHARED_AVAILABLE)
endif()
endif()
dep_option(SDL_DEPS_SHARED "Load dependencies dynamically" ON SDL_SHARED_AVAILABLE OFF)
set(SDL_SUBSYSTEMS )
macro(define_sdl_subsystem _name)
@@ -334,19 +322,19 @@ set_option(SDL_PTHREADS "Use POSIX threads for multi-threading" ${SDL
dep_option(SDL_PTHREADS_SEM "Use pthread semaphores" ON "SDL_PTHREADS" OFF)
dep_option(SDL_OSS "Support the OSS audio API" ${SDL_OSS_DEFAULT} "UNIX_SYS OR RISCOS;SDL_AUDIO" OFF)
dep_option(SDL_ALSA "Support the ALSA audio API" ${UNIX_SYS} "SDL_AUDIO" OFF)
dep_option(SDL_ALSA_SHARED "Dynamically load ALSA audio support" ON "SDL_ALSA" OFF)
dep_option(SDL_ALSA_SHARED "Dynamically load ALSA audio support" ON "SDL_ALSA;SDL_DEPS_SHARED" OFF)
dep_option(SDL_JACK "Support the JACK audio API" ${UNIX_SYS} "SDL_AUDIO" OFF)
dep_option(SDL_JACK_SHARED "Dynamically load JACK audio support" ON "SDL_JACK" OFF)
dep_option(SDL_JACK_SHARED "Dynamically load JACK audio support" ON "SDL_JACK;SDL_DEPS_SHARED" OFF)
set_option(SDL_PIPEWIRE "Use Pipewire audio" ${UNIX_SYS})
dep_option(SDL_PIPEWIRE_SHARED "Dynamically load Pipewire support" ON "SDL_PIPEWIRE" OFF)
dep_option(SDL_PIPEWIRE_SHARED "Dynamically load Pipewire support" ON "SDL_PIPEWIRE;SDL_DEPS_SHARED" OFF)
dep_option(SDL_PULSEAUDIO "Use PulseAudio" ${UNIX_SYS} "SDL_AUDIO" OFF)
dep_option(SDL_PULSEAUDIO_SHARED "Dynamically load PulseAudio support" ON "SDL_PULSEAUDIO" OFF)
dep_option(SDL_PULSEAUDIO_SHARED "Dynamically load PulseAudio support" ON "SDL_PULSEAUDIO;SDL_DEPS_SHARED" OFF)
dep_option(SDL_SNDIO "Support the sndio audio API" ${UNIX_SYS} "SDL_AUDIO" OFF)
dep_option(SDL_SNDIO_SHARED "Dynamically load the sndio audio API" ON "SDL_SNDIO" OFF)
dep_option(SDL_SNDIO_SHARED "Dynamically load the sndio audio API" ON "SDL_SNDIO;SDL_DEPS_SHARED" OFF)
set_option(SDL_RPATH "Use an rpath when linking SDL" ${SDL_RPATH_DEFAULT})
set_option(SDL_CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" ${SDL_CLOCK_GETTIME_DEFAULT})
dep_option(SDL_X11 "Use X11 video driver" ${UNIX_SYS} "SDL_VIDEO" OFF)
dep_option(SDL_X11_SHARED "Dynamically load X11 support" ON "SDL_X11" OFF)
dep_option(SDL_X11_SHARED "Dynamically load X11 support" ON "SDL_X11;SDL_DEPS_SHARED" OFF)
dep_option(SDL_X11_XCURSOR "Enable Xcursor support" ON SDL_X11 OFF)
dep_option(SDL_X11_XDBE "Enable Xdbe support" ON SDL_X11 OFF)
dep_option(SDL_X11_XINPUT "Enable XInput support" ON SDL_X11 OFF)
@@ -356,9 +344,9 @@ dep_option(SDL_X11_XSCRNSAVER "Enable Xscrnsaver support" ON SDL_X11 OFF)
dep_option(SDL_X11_XSHAPE "Enable XShape support" ON SDL_X11 OFF)
dep_option(SDL_X11_XSYNC "Enable Xsync support" ON SDL_X11 OFF)
dep_option(SDL_WAYLAND "Use Wayland video driver" ${UNIX_SYS} "SDL_VIDEO" OFF)
dep_option(SDL_WAYLAND_SHARED "Dynamically load Wayland support" ON "SDL_WAYLAND" OFF)
dep_option(SDL_WAYLAND_SHARED "Dynamically load Wayland support" ON "SDL_WAYLAND;SDL_DEPS_SHARED" OFF)
dep_option(SDL_WAYLAND_LIBDECOR "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF)
dep_option(SDL_WAYLAND_LIBDECOR_SHARED "Dynamically load libdecor support" ON "SDL_WAYLAND_LIBDECOR;SDL_WAYLAND_SHARED" OFF)
dep_option(SDL_WAYLAND_LIBDECOR_SHARED "Dynamically load libdecor support" ON "SDL_WAYLAND_LIBDECOR;SDL_WAYLAND_SHARED;SDL_DEPS_SHARED" OFF)
dep_option(SDL_RPI "Use Raspberry Pi video driver" ON "SDL_VIDEO;UNIX_SYS;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF)
dep_option(SDL_ROCKCHIP "Use ROCKCHIP Hardware Acceleration video driver" ON "SDL_VIDEO;UNIX_SYS;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF)
dep_option(SDL_COCOA "Use Cocoa video driver" ON "APPLE" OFF)
@@ -368,7 +356,7 @@ dep_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ON "WIN
dep_option(SDL_RENDER_D3D "Enable the Direct3D 9 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
dep_option(SDL_RENDER_D3D11 "Enable the Direct3D 11 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;${APPLE}" OFF)
dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;APPLE" OFF)
dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF)
dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF)
dep_option(SDL_VULKAN "Enable Vulkan support" ON "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR WINDOWS" OFF)
@@ -376,14 +364,14 @@ dep_option(SDL_RENDER_VULKAN "Enable the Vulkan render driver" ON "SDL_REN
dep_option(SDL_METAL "Enable Metal support" ON "APPLE" OFF)
set_option(SDL_OPENVR "Use OpenVR video driver" OFF)
dep_option(SDL_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS} "SDL_VIDEO" OFF)
dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF)
dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KMSDRM;SDL_DEPS_SHARED" OFF)
set_option(SDL_OFFSCREEN "Use offscreen video driver" ON)
dep_option(SDL_DUMMYCAMERA "Support the dummy camera driver" ON SDL_CAMERA 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)
dep_option(SDL_HIDAPI "Enable the HIDAPI subsystem" ON "NOT VISIONOS" OFF)
dep_option(SDL_HIDAPI_LIBUSB "Use libusb for low level joystick drivers" ON SDL_HIDAPI_LIBUSB_AVAILABLE OFF)
dep_option(SDL_HIDAPI_LIBUSB_SHARED "Dynamically load libusb support" ON SDL_HIDAPI_LIBUSB OFF)
dep_option(SDL_HIDAPI_LIBUSB_SHARED "Dynamically load libusb support" ON "SDL_HIDAPI_LIBUSB;SDL_DEPS_SHARED" OFF)
dep_option(SDL_HIDAPI_JOYSTICK "Use HIDAPI for low level joystick drivers" ON SDL_HIDAPI OFF)
dep_option(SDL_VIRTUAL_JOYSTICK "Enable the virtual-joystick driver" ON SDL_HIDAPI OFF)
set_option(SDL_LIBUDEV "Enable libudev support" ON)
@@ -419,6 +407,29 @@ if(SDL_PRESEED)
SDL_Preseed_CMakeCache()
endif()
if(MSVC)
if(NOT SDL_LIBC)
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
set(CMAKE_MSVC_RUNTIME_CHECKS "")
endif()
if(MSVC_CLANG)
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
endif()
endif()
if(SDL_SHARED)
add_library(SDL3-shared SHARED)
add_library(SDL3::SDL3-shared ALIAS SDL3-shared)
@@ -632,6 +643,11 @@ if(MSVC)
# Mark SDL3.dll as compatible with Control-flow Enforcement Technology (CET)
sdl_shared_link_options("-CETCOMPAT")
endif()
# for VS >= 17.14 targeting ARM64: inline the Interlocked funcs
if(MSVC_VERSION GREATER 1943 AND SDL_CPU_ARM64 AND NOT SDL_LIBC)
sdl_compile_options(PRIVATE "/forceInterlockedFunctions-")
endif()
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
@@ -648,7 +664,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mmmx")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <mmintrin.h>
void ints_add(int *dest, int *a, int *b, unsigned size) {
for (; size >= 2; size -= 2, dest += 2, a += 2, b += 2) {
@@ -658,7 +674,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char *argv[]) {
ints_add((int*)0, (int*)0, (int*)0, 0);
return 0;
}" COMPILER_SUPPORTS_MMX)
}]==] COMPILER_SUPPORTS_MMX)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_MMX)
set(HAVE_MMX TRUE)
@@ -669,7 +685,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <xmmintrin.h>
void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -679,7 +695,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) {
floats_add((float*)0, (float*)0, (float*)0, 0);
return 0;
}" COMPILER_SUPPORTS_SSE)
}]==] COMPILER_SUPPORTS_SSE)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE)
set(HAVE_SSE TRUE)
@@ -690,7 +706,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse2")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <emmintrin.h>
void doubles_add(double *dest, double *a, double *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -700,7 +716,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) {
doubles_add((double*)0, (double*)0, (double*)0, 0);
return 0;
}" COMPILER_SUPPORTS_SSE2)
}]==] COMPILER_SUPPORTS_SSE2)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE2)
set(HAVE_SSE2 TRUE)
@@ -711,7 +727,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse3")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <pmmintrin.h>
void ints_add(int *dest, int *a, int *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -721,7 +737,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) {
ints_add((int*)0, (int*)0, (int*)0, 0);
return 0;
}" COMPILER_SUPPORTS_SSE3)
}]==] COMPILER_SUPPORTS_SSE3)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE3)
set(HAVE_SSE3 TRUE)
@@ -732,7 +748,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.1")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <smmintrin.h>
void ints_mul(int *dest, int *a, int *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -742,7 +758,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) {
ints_mul((int*)0, (int*)0, (int*)0, 0);
return 0;
}" COMPILER_SUPPORTS_SSE4_1)
}]==] COMPILER_SUPPORTS_SSE4_1)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE4_1)
set(HAVE_SSE4_1 TRUE)
@@ -753,19 +769,14 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.2")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <nmmintrin.h>
unsigned calc_crc32c(const char *text, unsigned len) {
unsigned crc32c = ~0;
for (; len >= 4; len -= 4, text += 4) {
crc32c = (unsigned)_mm_crc32_u32(crc32c, *(unsigned*)text);
}
return crc32c;
}
__m128i bitmask;
char data[16];
int main(int argc, char **argv) {
calc_crc32c(\"SDL_SSE4\",8);
bitmask = _mm_cmpgt_epi64(_mm_set1_epi64x(0), _mm_loadu_si128((void*)data));
return 0;
}" COMPILER_SUPPORTS_SSE4_2)
}]==] COMPILER_SUPPORTS_SSE4_2)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE4_2)
set(HAVE_SSE4_2 TRUE)
@@ -776,7 +787,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <immintrin.h>
void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
@@ -786,7 +797,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) {
floats_add((float*)0, (float*)0, (float*)0, 0);
return 0;
}" COMPILER_SUPPORTS_AVX)
}]==] COMPILER_SUPPORTS_AVX)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_AVX)
set(HAVE_AVX TRUE)
@@ -797,7 +808,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx2")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <immintrin.h>
void ints_add(int *dest, int *a, int *b, unsigned size) {
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
@@ -807,7 +818,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) {
ints_add((int*)0, (int*)0, (int*)0, 0);
return 0;
}" COMPILER_SUPPORTS_AVX2)
}]==] COMPILER_SUPPORTS_AVX2)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_AVX2)
set(HAVE_AVX2 TRUE)
@@ -818,7 +829,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx512f")
endif()
check_c_source_compiles("
check_x86_source_compiles([==[
#include <immintrin.h>
void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 16; size -= 16, dest += 16, a += 16, b += 16) {
@@ -828,7 +839,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) {
floats_add((float*)0, (float*)0, (float*)0, 0);
return 0;
}" COMPILER_SUPPORTS_AVX512F)
}]==] COMPILER_SUPPORTS_AVX512F)
cmake_pop_check_state()
if(COMPILER_SUPPORTS_AVX512F)
set(HAVE_AVX512F TRUE)
@@ -836,7 +847,7 @@ if(SDL_ASSEMBLY)
endif()
if(SDL_ARMNEON)
check_c_source_compiles("
check_arm_source_compiles([==[
#include <arm_neon.h>
void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -846,8 +857,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char *argv[]) {
floats_add((float*)0, (float*)0, (float*)0, 0);
return 0;
}" COMPILER_SUPPORTS_ARMNEON)
}]==] COMPILER_SUPPORTS_ARMNEON)
if(COMPILER_SUPPORTS_ARMNEON)
set(HAVE_ARMNEON TRUE)
endif()
@@ -1050,8 +1060,10 @@ if(SDL_LIBC)
cmake_push_check_state()
if(MSVC)
string(APPEND CMAKE_REQUIRED_FLAGS " -we4244 -WX") # 'conversion' conversion from 'type1' to 'type2', possible loss of data
else()
elseif(HAVE_GCC_WFLOAT_CONVERSION)
string(APPEND CMAKE_REQUIRED_FLAGS " -Wfloat-conversion -Werror")
else()
string(APPEND CMAKE_REQUIRED_FLAGS " -Wconversion -Werror")
endif()
foreach(math_fn isinf isnan)
string(TOUPPER "${math_fn}" MATH_FN)
@@ -1089,6 +1101,7 @@ if(SDL_LIBC)
check_symbol_exists(gethostname "unistd.h" HAVE_GETHOSTNAME)
check_symbol_exists(getpagesize "unistd.h" HAVE_GETPAGESIZE)
check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
check_symbol_exists(sigtimedwait "signal.h" HAVE_SIGTIMEDWAIT)
check_symbol_exists(setjmp "setjmp.h" HAVE_SETJMP)
check_symbol_exists(nanosleep "time.h" HAVE_NANOSLEEP)
check_symbol_exists(gmtime_r "time.h" HAVE_GMTIME_R)
@@ -1289,8 +1302,8 @@ if(ANDROID)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/android")
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/android/*.c")
sdl_sources("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")
set_property(SOURCE "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-declaration-after-statement")
sdl_sources("${CMAKE_ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")
set_property(SOURCE "${CMAKE_ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-declaration-after-statement")
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/misc/android/*.c")
set(HAVE_SDL_MISC TRUE)
@@ -1334,9 +1347,7 @@ if(ANDROID)
set(HAVE_SDL_HAPTIC TRUE)
endif()
if(SDL_HIDAPI)
CheckHIDAPI()
endif()
if(SDL_JOYSTICK)
set(SDL_JOYSTICK_ANDROID 1)
@@ -2186,6 +2197,7 @@ elseif(APPLE)
set(SDL_CAMERA_DRIVER_COREMEDIA 1)
set(HAVE_CAMERA TRUE)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/coremedia/*.m")
set(SDL_FRAMEWORK_AVFOUNDATION 1)
endif()
endif()
@@ -2887,6 +2899,7 @@ elseif(N3DS)
set(SDL_THREAD_N3DS 1)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/thread/n3ds/*.c")
sdl_sources(
"${SDL3_SOURCE_DIR}/src/thread/generic/SDL_syscond.c"
"${SDL3_SOURCE_DIR}/src/thread/generic/SDL_systls.c"
"${SDL3_SOURCE_DIR}/src/thread/generic/SDL_sysrwlock.c"
)
@@ -2950,7 +2963,7 @@ if(WINDOWS)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/process/windows/*.c")
set(SDL_PROCESS_WINDOWS 1)
set(HAVE_SDL_PROCESS TRUE)
else()
elseif(NOT ANDROID)
check_c_source_compiles("
#include <spawn.h>
#include <unistd.h>
@@ -3013,7 +3026,7 @@ if(SDL_GPU)
set(SDL_GPU_D3D11 1)
set(HAVE_SDL_GPU TRUE)
endif()
if(SDL_RENDER_D3D12)
if(WINDOWS)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/gpu/d3d12/*.c")
set(SDL_GPU_D3D12 1)
set(HAVE_SDL_GPU TRUE)
@@ -3140,14 +3153,15 @@ endforeach()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt")
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt" revisions)
list(GET revisions 0 revisions_0)
string(STRIP "${revisions_0}" SDL_REVISION)
string(STRIP "${revisions_0}" revisions_0_stripped)
set(SDL_REVISION "SDL-${revisions_0_stripped}")
else()
set(SDL_REVISION "" CACHE STRING "Custom SDL revision (only used when REVISION.txt does not exist)")
endif()
if(NOT SDL_REVISION)
# If SDL_REVISION is not overrided, use git to describe
git_describe(SDL_REVISION_GIT)
set(SDL_REVISION "SDL3-${SDL3_VERSION}-${SDL_REVISION_GIT}")
set(SDL_REVISION "SDL-${SDL3_VERSION}-${SDL_REVISION_GIT}")
endif()
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${SDL3_BINARY_DIR}/include-revision/SDL3")
@@ -3284,7 +3298,7 @@ else()
endif()
if(ANDROID)
sdl_include_directories(PRIVATE SYSTEM "${ANDROID_NDK}/sources/android/cpufeatures")
sdl_include_directories(PRIVATE SYSTEM "${CMAKE_ANDROID_NDK}/sources/android/cpufeatures")
endif()
if(APPLE)

View File

@@ -3,6 +3,7 @@
SDL supports a number of development environments:
- [CMake](docs/INTRO-cmake.md)
- [Visual Studio on Windows](docs/INTRO-visualstudio.md)
- [gcc on Windows](docs/INTRO-mingw.md)
- [Xcode on Apple platforms](docs/INTRO-xcode.md)
- [Android Studio](docs/INTRO-androidstudio.md)
- [Emscripten for web](docs/INTRO-emscripten.md)

View File

@@ -168,8 +168,8 @@
</Link>
<PreBuildEvent>
<Command>
call $(ProjectDir)..\..\src\render\direct3d12\compile_shaders_xbox.bat $(ProjectDir)..\
call $(ProjectDir)..\..\src\gpu\d3d12\compile_shaders_xbox.bat $(ProjectDir)..\
call "$(ProjectDir)..\..\src\render\direct3d12\compile_shaders_xbox.bat" "$(ProjectDir)..\"
call "$(ProjectDir)..\..\src\gpu\d3d12\compile_shaders_xbox.bat" "$(ProjectDir)..\"
</Command>
</PreBuildEvent>
<PreBuildEvent>
@@ -425,6 +425,7 @@
<ClInclude Include="..\..\src\camera\SDL_syscamera.h" />
<ClInclude Include="..\..\src\core\gdk\SDL_gdk.h" />
<ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
<ClInclude Include="..\..\src\core\windows\SDL_gameinput.h" />
<ClInclude Include="..\..\src\core\windows\SDL_hid.h" />
<ClInclude Include="..\..\src\core\windows\SDL_immdevice.h" />
<ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
@@ -441,6 +442,7 @@
<ClInclude Include="..\..\src\events\SDL_displayevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_events_c.h" />
<ClInclude Include="..\..\src\events\SDL_eventwatch_c.h" />
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
<ClInclude Include="..\..\src\events\SDL_keymap_c.h" />
<ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
@@ -594,6 +596,7 @@
<ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
<ClInclude Include="..\..\src\video\SDL_rect_c.h" />
<ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
<ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
@@ -640,6 +643,7 @@
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
<ClCompile Include="..\..\src\core\windows\SDL_gameinput.c"/>
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
@@ -673,6 +677,7 @@
<ClCompile Include="..\..\src\events\SDL_displayevents.c" />
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
<ClCompile Include="..\..\src\events\SDL_events.c" />
<ClCompile Include="..\..\src\events\SDL_eventwatch.c" />
<ClCompile Include="..\..\src\events\SDL_keyboard.c" />
<ClCompile Include="..\..\src\events\SDL_keymap.c" />
<ClCompile Include="..\..\src\events\SDL_mouse.c" />
@@ -868,6 +873,7 @@
<ClCompile Include="..\..\src\video\SDL_pixels.c" />
<ClCompile Include="..\..\src\video\SDL_rect.c" />
<ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
<ClCompile Include="..\..\src\video\SDL_stb.c" />
<ClCompile Include="..\..\src\video\SDL_stretch.c" />
<ClCompile Include="..\..\src\video\SDL_surface.c" />
<ClCompile Include="..\..\src\video\SDL_video.c" />

View File

@@ -27,6 +27,7 @@
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
<ClCompile Include="..\..\src\core\windows\SDL_gameinput.c" />
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
@@ -38,6 +39,7 @@
<ClCompile Include="..\..\src\events\SDL_displayevents.c" />
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
<ClCompile Include="..\..\src\events\SDL_events.c" />
<ClCompile Include="..\..\src\events\SDL_eventwatch.c" />
<ClCompile Include="..\..\src\events\SDL_keyboard.c" />
<ClCompile Include="..\..\src\events\SDL_keymap.c" />
<ClCompile Include="..\..\src\events\SDL_mouse.c" />
@@ -175,6 +177,7 @@
<ClCompile Include="..\..\src\video\SDL_pixels.c" />
<ClCompile Include="..\..\src\video\SDL_rect.c" />
<ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
<ClCompile Include="..\..\src\video\SDL_stb.c" />
<ClCompile Include="..\..\src\video\SDL_stretch.c" />
<ClCompile Include="..\..\src\video\SDL_surface.c" />
<ClCompile Include="..\..\src\video\SDL_video.c" />
@@ -314,6 +317,7 @@
<ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
<ClInclude Include="..\..\src\core\gdk\SDL_gdk.h" />
<ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
<ClInclude Include="..\..\src\core\windows\SDL_gameinput.h" />
<ClInclude Include="..\..\src\core\windows\SDL_hid.h" />
<ClInclude Include="..\..\src\core\windows\SDL_immdevice.h" />
<ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
@@ -330,6 +334,7 @@
<ClInclude Include="..\..\src\events\SDL_displayevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_events_c.h" />
<ClInclude Include="..\..\src\events\SDL_eventwatch_c.h" />
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
<ClInclude Include="..\..\src\events\SDL_keymap_c.h" />
<ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
@@ -434,6 +439,7 @@
<ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
<ClInclude Include="..\..\src\video\SDL_rect_c.h" />
<ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
<ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />

View File

@@ -336,6 +336,7 @@
<ClInclude Include="..\..\src\camera\SDL_camera_c.h" />
<ClInclude Include="..\..\src\camera\SDL_syscamera.h" />
<ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
<ClInclude Include="..\..\src\core\windows\SDL_gameinput.h" />
<ClInclude Include="..\..\src\core\windows\SDL_hid.h" />
<ClInclude Include="..\..\src\core\windows\SDL_immdevice.h" />
<ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
@@ -353,6 +354,7 @@
<ClInclude Include="..\..\src\events\SDL_displayevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
<ClInclude Include="..\..\src\events\SDL_events_c.h" />
<ClInclude Include="..\..\src\events\SDL_eventwatch_c.h" />
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
<ClInclude Include="..\..\src\events\SDL_keymap_c.h" />
<ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
@@ -492,6 +494,7 @@
<ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
<ClInclude Include="..\..\src\video\SDL_rect_c.h" />
<ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
<ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
@@ -538,6 +541,7 @@
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
<ClCompile Include="..\..\src\core\windows\SDL_gameinput.c" />
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
@@ -555,6 +559,7 @@
<ClCompile Include="..\..\src\events\SDL_displayevents.c" />
<ClCompile Include="..\..\src\events\SDL_dropevents.c" />
<ClCompile Include="..\..\src\events\SDL_events.c" />
<ClCompile Include="..\..\src\events\SDL_eventwatch.c" />
<ClCompile Include="..\..\src\events\SDL_keyboard.c" />
<ClCompile Include="..\..\src\events\SDL_keymap.c" />
<ClCompile Include="..\..\src\events\SDL_mouse.c" />
@@ -703,6 +708,7 @@
<ClCompile Include="..\..\src\video\SDL_pixels.c" />
<ClCompile Include="..\..\src\video\SDL_rect.c" />
<ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
<ClCompile Include="..\..\src\video\SDL_stb.c" />
<ClCompile Include="..\..\src\video\SDL_stretch.c" />
<ClCompile Include="..\..\src\video\SDL_surface.c" />
<ClCompile Include="..\..\src\video\SDL_video.c" />

View File

@@ -486,6 +486,12 @@
<ClInclude Include="..\..\src\audio\SDL_audioresample.h">
<Filter>audio</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\windows\SDL_directx.h">
<Filter>core\windows</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\windows\SDL_gameinput.h">
<Filter>core\windows</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\windows\SDL_hid.h">
<Filter>core\windows</Filter>
</ClInclude>
@@ -528,6 +534,9 @@
<ClInclude Include="..\..\src\events\SDL_events_c.h">
<Filter>events</Filter>
</ClInclude>
<ClInclude Include="..\..\src\events\SDL_eventfilter_c.h">
<Filter>events</Filter>
</ClInclude>
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h">
<Filter>events</Filter>
</ClInclude>
@@ -666,6 +675,9 @@
<ClInclude Include="..\..\src\video\SDL_egl_c.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="..\..\src\video\SDL_stb_c.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="..\..\src\video\SDL_yuv_c.h">
<Filter>video</Filter>
</ClInclude>
@@ -1028,6 +1040,9 @@
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\windows\SDL_gameinput.c">
<Filter>core\windows</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\windows\SDL_hid.c">
<Filter>core\windows</Filter>
</ClCompile>
@@ -1064,6 +1079,9 @@
<ClCompile Include="..\..\src\events\SDL_events.c">
<Filter>events</Filter>
</ClCompile>
<ClCompile Include="..\..\src\events\SDL_eventfilter.c">
<Filter>events</Filter>
</ClCompile>
<ClCompile Include="..\..\src\events\SDL_keyboard.c">
<Filter>events</Filter>
</ClCompile>
@@ -1283,6 +1301,9 @@
<ClCompile Include="..\..\src\video\SDL_rect.c">
<Filter>video</Filter>
</ClCompile>
<ClCompile Include="..\..\src\video\SDL_stb.c">
<Filter>video</Filter>
</ClCompile>
<ClCompile Include="..\..\src\video\SDL_stretch.c">
<Filter>video</Filter>
</ClCompile>

View File

@@ -1,6 +1,16 @@
This is a list of major changes in SDL's version history.
---------------------------------------------------------------------------
3.2.10:
---------------------------------------------------------------------------
* Added SDL_HINT_VIDEO_X11_EXTERNAL_WINDOW_INPUT to control whether XSelectInput() should be called on external windows to enable input events.
---------------------------------------------------------------------------
3.2.4:
---------------------------------------------------------------------------
* Added SDL_StretchSurface()
---------------------------------------------------------------------------
3.2.0:
---------------------------------------------------------------------------

View File

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

View File

@@ -512,10 +512,16 @@
F3D46B122D20625800D9CBDF /* SDL_egl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D46A8E2D20625800D9CBDF /* SDL_egl.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3D46B132D20625800D9CBDF /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D46A922D20625800D9CBDF /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3D60A8328C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; };
F3D8BDFC2D6D2C7000B22FA1 /* SDL_eventwatch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D8BDFB2D6D2C7000B22FA1 /* SDL_eventwatch_c.h */; };
F3D8BDFD2D6D2C7000B22FA1 /* SDL_eventwatch.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D8BDFA2D6D2C7000B22FA1 /* SDL_eventwatch.c */; };
F3DDCC562AFD42B600B0842B /* SDL_clipboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */; };
F3DDCC5B2AFD42B600B0842B /* SDL_video_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC522AFD42B600B0842B /* SDL_video_c.h */; };
F3DDCC5D2AFD42B600B0842B /* SDL_rect_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */; };
F3E5A6EB2AD5E0E600293D83 /* SDL_properties.c in Sources */ = {isa = PBXBuildFile; fileRef = F3E5A6EA2AD5E0E600293D83 /* SDL_properties.c */; };
F3EFA5ED2D5AB97300BCF22F /* SDL_stb_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3EFA5EA2D5AB97300BCF22F /* SDL_stb_c.h */; };
F3EFA5EE2D5AB97300BCF22F /* stb_image.h in Headers */ = {isa = PBXBuildFile; fileRef = F3EFA5EC2D5AB97300BCF22F /* stb_image.h */; };
F3EFA5EF2D5AB97300BCF22F /* SDL_surface_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3EFA5EB2D5AB97300BCF22F /* SDL_surface_c.h */; };
F3EFA5F02D5AB97300BCF22F /* SDL_stb.c in Sources */ = {isa = PBXBuildFile; fileRef = F3EFA5E92D5AB97300BCF22F /* SDL_stb.c */; };
F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; };
F3F15D7F2D011912007AE210 /* SDL_dialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F15D7D2D011912007AE210 /* SDL_dialog.c */; };
F3F15D802D011912007AE210 /* SDL_dialog_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F15D7E2D011912007AE210 /* SDL_dialog_utils.h */; };
@@ -1075,10 +1081,16 @@
F3D46AC82D20625800D9CBDF /* SDL_video.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_video.h; sourceTree = "<group>"; };
F3D46AC92D20625800D9CBDF /* SDL_vulkan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = "<group>"; };
F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_wii.c; sourceTree = "<group>"; };
F3D8BDFA2D6D2C7000B22FA1 /* SDL_eventwatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_eventwatch.c; sourceTree = "<group>"; };
F3D8BDFB2D6D2C7000B22FA1 /* SDL_eventwatch_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_eventwatch_c.h; sourceTree = "<group>"; };
F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_clipboard_c.h; sourceTree = "<group>"; };
F3DDCC522AFD42B600B0842B /* SDL_video_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_video_c.h; sourceTree = "<group>"; };
F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_rect_impl.h; sourceTree = "<group>"; };
F3E5A6EA2AD5E0E600293D83 /* SDL_properties.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_properties.c; sourceTree = "<group>"; };
F3EFA5E92D5AB97300BCF22F /* SDL_stb.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_stb.c; sourceTree = "<group>"; };
F3EFA5EA2D5AB97300BCF22F /* SDL_stb_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_stb_c.h; sourceTree = "<group>"; };
F3EFA5EB2D5AB97300BCF22F /* SDL_surface_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_surface_c.h; sourceTree = "<group>"; };
F3EFA5EC2D5AB97300BCF22F /* stb_image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stb_image.h; sourceTree = "<group>"; };
F3F07D59269640160074468B /* SDL_hidapi_luna.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_luna.c; sourceTree = "<group>"; };
F3F15D7C2D011912007AE210 /* SDL_dialog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_dialog.h; sourceTree = "<group>"; };
F3F15D7D2D011912007AE210 /* SDL_dialog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_dialog.c; sourceTree = "<group>"; };
@@ -1586,43 +1598,47 @@
A7D8A60523E2513D00DCD162 /* dummy */,
A7D8A72123E2513E00DCD162 /* khronos */,
A7D8A5EC23E2513D00DCD162 /* offscreen */,
A7D8A61823E2513D00DCD162 /* uikit */,
A7D8A76C23E2513E00DCD162 /* yuv2rgb */,
A7D8A76B23E2513E00DCD162 /* SDL_blit.h */,
A7D8A64C23E2513D00DCD162 /* SDL_blit.c */,
A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */,
A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */,
A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */,
A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */,
A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */,
A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */,
A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */,
A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */,
A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */,
A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */,
A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */,
A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */,
A7D8A64C23E2513D00DCD162 /* SDL_blit.c */,
A7D8A76B23E2513E00DCD162 /* SDL_blit.h */,
A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */,
A7D8A77323E2513E00DCD162 /* SDL_bmp.c */,
F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */,
A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */,
A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */,
F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */,
A7D8A6B623E2513E00DCD162 /* SDL_egl.c */,
A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */,
A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */,
A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */,
A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */,
A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */,
A7D8A63423E2513D00DCD162 /* SDL_rect.c */,
A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */,
F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */,
A7D8A63423E2513D00DCD162 /* SDL_rect.c */,
A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */,
A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */,
A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */,
F3EFA5E92D5AB97300BCF22F /* SDL_stb.c */,
F3EFA5EA2D5AB97300BCF22F /* SDL_stb_c.h */,
A7D8A60323E2513D00DCD162 /* SDL_stretch.c */,
A7D8A61423E2513D00DCD162 /* SDL_surface.c */,
F3EFA5EB2D5AB97300BCF22F /* SDL_surface_c.h */,
A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */,
A7D8A60E23E2513D00DCD162 /* SDL_video.c */,
F3DDCC522AFD42B600B0842B /* SDL_video_c.h */,
E4F7981F2AD8D87F00669F54 /* SDL_video_unsupported.c */,
A7D8A60E23E2513D00DCD162 /* SDL_video.c */,
A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */,
A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */,
A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */,
A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */,
A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */,
F3EFA5EC2D5AB97300BCF22F /* stb_image.h */,
A7D8A61823E2513D00DCD162 /* uikit */,
A7D8A76C23E2513E00DCD162 /* yuv2rgb */,
);
path = video;
sourceTree = "<group>";
@@ -2197,29 +2213,31 @@
A7D8A93623E2514000DCD162 /* scancodes_linux.h */,
A7D8A92C23E2514000DCD162 /* scancodes_windows.h */,
A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */,
F3C2CB202C5DDDB2004D7998 /* SDL_categories_c.h */,
F3C2CB212C5DDDB2004D7998 /* SDL_categories.c */,
A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */,
F3C2CB202C5DDDB2004D7998 /* SDL_categories_c.h */,
A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */,
A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */,
A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */,
A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */,
A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */,
A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */,
A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */,
A7D8A94223E2514000DCD162 /* SDL_events_c.h */,
A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */,
A7D8A93523E2514000DCD162 /* SDL_events.c */,
A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */,
A7D8A94223E2514000DCD162 /* SDL_events_c.h */,
F3D8BDFA2D6D2C7000B22FA1 /* SDL_eventwatch.c */,
F3D8BDFB2D6D2C7000B22FA1 /* SDL_eventwatch_c.h */,
A7D8A93823E2514000DCD162 /* SDL_keyboard.c */,
F31013C62C24E98200FBE946 /* SDL_keymap_c.h */,
A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */,
F31013C52C24E98200FBE946 /* SDL_keymap.c */,
A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */,
F31013C62C24E98200FBE946 /* SDL_keymap_c.h */,
A7D8A92A23E2514000DCD162 /* SDL_mouse.c */,
63134A232A7902FD0021E9A6 /* SDL_pen_c.h */,
A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */,
63134A242A7902FD0021E9A6 /* SDL_pen.c */,
63134A232A7902FD0021E9A6 /* SDL_pen_c.h */,
A7D8A93C23E2514000DCD162 /* SDL_quit.c */,
A7D8A93723E2514000DCD162 /* SDL_touch_c.h */,
A7D8A93E23E2514000DCD162 /* SDL_touch.c */,
A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */,
A7D8A93723E2514000DCD162 /* SDL_touch_c.h */,
A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */,
A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */,
);
path = events;
sourceTree = "<group>";
@@ -2458,6 +2476,9 @@
A7D8BB6F23E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */,
A7D8AECA23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */,
A7D8AF1223E2514100DCD162 /* SDL_cocoaevents.h in Headers */,
F3EFA5ED2D5AB97300BCF22F /* SDL_stb_c.h in Headers */,
F3EFA5EE2D5AB97300BCF22F /* stb_image.h in Headers */,
F3EFA5EF2D5AB97300BCF22F /* SDL_surface_c.h in Headers */,
A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */,
A7D8AF0623E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */,
A7D8AEB223E2514100DCD162 /* SDL_cocoametalview.h in Headers */,
@@ -2692,6 +2713,7 @@
A7D8B3D423E2514300DCD162 /* yuv_rgb.h in Headers */,
F3FA5A252B59ACE000FEAD97 /* yuv_rgb_common.h in Headers */,
F3FA5A1D2B59ACE000FEAD97 /* yuv_rgb_internal.h in Headers */,
F3D8BDFC2D6D2C7000B22FA1 /* SDL_eventwatch_c.h in Headers */,
F3FA5A242B59ACE000FEAD97 /* yuv_rgb_lsx.h in Headers */,
F3FA5A1E2B59ACE000FEAD97 /* yuv_rgb_lsx_func.h in Headers */,
F3FA5A1F2B59ACE000FEAD97 /* yuv_rgb_sse.h in Headers */,
@@ -2950,6 +2972,8 @@
566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */,
A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */,
A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */,
F3D8BDFD2D6D2C7000B22FA1 /* SDL_eventwatch.c in Sources */,
F3EFA5F02D5AB97300BCF22F /* SDL_stb.c in Sources */,
A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */,
A7D8B3DA23E2514300DCD162 /* SDL_bmp.c in Sources */,
A7D8B96E23E2514400DCD162 /* SDL_stdlib.c in Sources */,
@@ -3062,7 +3086,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
DEPLOYMENT_POSTPROCESSING = YES;
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.4.0;
DYLIB_CURRENT_VERSION = 201.24.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ALTIVEC_EXTENSIONS = YES;
@@ -3097,7 +3121,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.2.4;
MARKETING_VERSION = 3.2.24;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
PRODUCT_NAME = SDL3;
@@ -3126,7 +3150,7 @@
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.4.0;
DYLIB_CURRENT_VERSION = 201.24.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -3158,7 +3182,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.2.4;
MARKETING_VERSION = 3.2.24;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;

View File

@@ -1,4 +1,4 @@
Title SDL 3.2.4
Title SDL 3.2.24
Version 1
Description SDL Library for macOS (http://www.libsdl.org)
DefaultLocation /Library/Frameworks

View File

@@ -92,7 +92,7 @@ if(NOT TARGET SDL3::Headers)
add_library(SDL3::Headers INTERFACE IMPORTED)
set_target_properties(SDL3::Headers
PROPERTIES
INTERFACE_COMPILE_OPTIONS "SHELL:-F \"${_sdl3_framework_parent_path}\""
INTERFACE_COMPILE_OPTIONS "-F${_sdl3_framework_parent_path}"
)
endif()
set(SDL3_Headers_FOUND TRUE)

View File

@@ -167,6 +167,9 @@
F399C6512A7892D800C86979 /* testautomation_intrinsics.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6502A7892D800C86979 /* testautomation_intrinsics.c */; };
F399C6522A7892D800C86979 /* testautomation_intrinsics.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6502A7892D800C86979 /* testautomation_intrinsics.c */; };
F399C6552A78933100C86979 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F399C6542A78933000C86979 /* Cocoa.framework */; };
F3B7FD642D73FC630086D1D0 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; };
F3B7FD662D73FC630086D1D0 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F3B7FD6C2D73FC9E0086D1D0 /* testpen.c in Sources */ = {isa = PBXBuildFile; fileRef = F3B7FD6B2D73FC9E0086D1D0 /* testpen.c */; };
F3C17C7728E40BC800E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; };
F3C17C7928E40C6E00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; };
F3C17C7B28E40D4E00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; };
@@ -717,6 +720,17 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
F3B7FD652D73FC630086D1D0 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
F3B7FD662D73FC630086D1D0 /* SDL3.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
F3CB568B2A7895F800766177 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@@ -1356,6 +1370,8 @@
F399C6492A78929400C86979 /* gamepadutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gamepadutils.c; sourceTree = "<group>"; };
F399C6502A7892D800C86979 /* testautomation_intrinsics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_intrinsics.c; sourceTree = "<group>"; };
F399C6542A78933000C86979 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
F3B7FD6A2D73FC630086D1D0 /* testpen.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testpen.app; sourceTree = BUILT_PRODUCTS_DIR; };
F3B7FD6B2D73FC9E0086D1D0 /* testpen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testpen.c; sourceTree = "<group>"; };
F3C17C6A28E3FD4400E1A26D /* config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = "<group>"; };
F3C17C7328E40ADE00E1A26D /* testutils.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testutils.c; sourceTree = "<group>"; };
F3C17CD628E416AC00E1A26D /* testgeometry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testgeometry.c; sourceTree = "<group>"; };
@@ -1732,6 +1748,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
F3B7FD632D73FC630086D1D0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F3B7FD642D73FC630086D1D0 /* SDL3.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F3C17CD928E416CF00E1A26D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -1789,6 +1813,7 @@
083E4872006D84C97F000001 /* loopwave.c */,
0017958F1074216E00F5D044 /* testatomic.c */,
001795B01074222D00F5D044 /* testaudioinfo.c */,
F35E56CC2983130F00A43A5F /* testautomation.c */,
F35E56C42983130D00A43A5F /* testautomation_audio.c */,
F35E56BC2983130B00A43A5F /* testautomation_clipboard.c */,
F35E56BB2983130B00A43A5F /* testautomation_events.c */,
@@ -1815,7 +1840,6 @@
A1A8594B2BC72FC20045DD6C /* testautomation_time.c */,
F35E56BD2983130B00A43A5F /* testautomation_timer.c */,
F35E56C12983130C00A43A5F /* testautomation_video.c */,
F35E56CC2983130F00A43A5F /* testautomation.c */,
F36C342C2C0F869B00991150 /* testcamera.c */,
BBFC088E164C6820003E6A99 /* testcontroller.c */,
001797711074320D00F5D044 /* testdraw.c */,
@@ -1837,11 +1861,12 @@
092D6D75FFB313BB7F000001 /* testlock.c */,
DB166CBD16A1C74100A1396C /* testmessage.c */,
001798151074359B00F5D044 /* testmultiaudio.c */,
0017985A107436ED00F5D044 /* testnative.c */,
0017985B107436ED00F5D044 /* testnative.h */,
0017985A107436ED00F5D044 /* testnative.c */,
0017985C107436ED00F5D044 /* testnativecocoa.m */,
00179872107438D000F5D044 /* testnativex11.c */,
002F345209CA201C00EBEB88 /* testoverlay.c */,
F3B7FD6B2D73FC9E0086D1D0 /* testpen.c */,
002F346F09CA20A600EBEB88 /* testplatform.c */,
001798B910743A4900F5D044 /* testpower.c */,
DB166CBF16A1C74100A1396C /* testrelative.c */,
@@ -1918,6 +1943,7 @@
F3C17CDC28E416CF00E1A26D /* testgeometry.app */,
F35E56AA298312CB00A43A5F /* testautomation.app */,
F36C34272C0F85DB00991150 /* testcamera.app */,
F3B7FD6A2D73FC630086D1D0 /* testpen.app */,
);
name = Products;
sourceTree = "<group>";
@@ -2756,6 +2782,23 @@
productReference = F36C34272C0F85DB00991150 /* testcamera.app */;
productType = "com.apple.product-type.application";
};
F3B7FD602D73FC630086D1D0 /* testpen */ = {
isa = PBXNativeTarget;
buildConfigurationList = F3B7FD672D73FC630086D1D0 /* Build configuration list for PBXNativeTarget "testpen" */;
buildPhases = (
F3B7FD612D73FC630086D1D0 /* Sources */,
F3B7FD632D73FC630086D1D0 /* Frameworks */,
F3B7FD652D73FC630086D1D0 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = testpen;
productName = testalpha;
productReference = F3B7FD6A2D73FC630086D1D0 /* testpen.app */;
productType = "com.apple.product-type.application";
};
F3C17CDB28E416CF00E1A26D /* testgeometry */ = {
isa = PBXNativeTarget;
buildConfigurationList = F3C17CE828E416D000E1A26D /* Build configuration list for PBXNativeTarget "testgeometry" */;
@@ -2972,6 +3015,7 @@
001798781074392D00F5D044 /* testnative */,
002F343C09CA1FB300EBEB88 /* testoverlay */,
002F345909CA204F00EBEB88 /* testplatform */,
F3B7FD602D73FC630086D1D0 /* testpen */,
0017989D107439DF00F5D044 /* testpower */,
DB166DDC16A1D50C00A1396C /* testrelative */,
DB166DF316A1D57C00A1396C /* testrendercopyex */,
@@ -3455,6 +3499,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
F3B7FD612D73FC630086D1D0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F3B7FD6C2D73FC9E0086D1D0 /* testpen.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F3C17CD828E416CF00E1A26D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -4704,6 +4756,26 @@
};
name = Release;
};
F3B7FD682D73FC630086D1D0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
};
name = Debug;
};
F3B7FD692D73FC630086D1D0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
};
name = Release;
};
F3C17CE928E416D000E1A26D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -5159,6 +5231,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
F3B7FD672D73FC630086D1D0 /* Build configuration list for PBXNativeTarget "testpen" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F3B7FD682D73FC630086D1D0 /* Debug */,
F3B7FD692D73FC630086D1D0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
F3C17CE828E416D000E1A26D /* Build configuration list for PBXNativeTarget "testgeometry" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@@ -5,7 +5,7 @@ plugins {
def buildWithCMake = project.hasProperty('BUILD_WITH_CMAKE');
android {
namespace "org.libsdl.app"
namespace = "org.libsdl.app"
compileSdkVersion 35
defaultConfig {
minSdkVersion 21
@@ -14,12 +14,12 @@ android {
versionName "1.0"
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-19"
arguments "APP_PLATFORM=android-21"
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'arm64-v8a'
}
cmake {
arguments "-DANDROID_PLATFORM=android-19", "-DANDROID_STL=c++_static"
arguments "-DANDROID_PLATFORM=android-21", "-DANDROID_STL=c++_static"
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'arm64-v8a'
}
@@ -53,7 +53,7 @@ android {
}
lint {
abortOnError false
abortOnError = false
}
}

View File

@@ -7,4 +7,4 @@
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
# Min runtime API level
APP_PLATFORM=android-16
APP_PLATFORM=android-21

View File

@@ -51,6 +51,8 @@
boolean supportsRelativeMouse();
int openFileDescriptor(java.lang.String, java.lang.String);
boolean showFileDialog(java.lang.String[], boolean, boolean, int);
java.lang.String getPreferredLocales();
java.lang.String formatLocale(java.util.Locale);
}
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {

View File

@@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.LocaleList;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.DisplayMetrics;
@@ -60,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 3;
private static final int SDL_MINOR_VERSION = 2;
private static final int SDL_MICRO_VERSION = 4;
private static final int SDL_MICRO_VERSION = 24;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
@@ -2116,6 +2117,44 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
int requestCode;
boolean multipleChoice;
}
/**
* This method is called by SDL using JNI.
*/
public static String getPreferredLocales() {
String result = "";
if (Build.VERSION.SDK_INT >= 24 /* Android 7 (N) */) {
LocaleList locales = LocaleList.getAdjustedDefault();
for (int i = 0; i < locales.size(); i++) {
if (i != 0) result += ",";
result += formatLocale(locales.get(i));
}
} else if (mCurrentLocale != null) {
result = formatLocale(mCurrentLocale);
}
return result;
}
public static String formatLocale(Locale locale) {
String result = "";
String lang = "";
if (locale.getLanguage() == "in") {
// Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility
lang = "id";
} else if (locale.getLanguage() == "") {
// Make sure language is never empty
lang = "und";
} else {
lang = locale.getLanguage();
}
if (locale.getCountry() == "") {
result = lang;
} else {
result = lang + "_" + locale.getCountry();
}
return result;
}
}
/**
@@ -2157,7 +2196,11 @@ class SDLClipboardHandler implements
}
public boolean clipboardHasText() {
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
return mClipMgr.hasPrimaryClip();
} else {
return mClipMgr.hasText();
}
}
public String clipboardGetText() {
@@ -2176,8 +2219,17 @@ class SDLClipboardHandler implements
public void clipboardSetText(String string) {
mClipMgr.removePrimaryClipChangedListener(this);
if (string.isEmpty()) {
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
mClipMgr.clearPrimaryClip();
} else {
ClipData clip = ClipData.newPlainText(null, "");
mClipMgr.setPrimaryClip(clip);
}
} else {
ClipData clip = ClipData.newPlainText(null, string);
mClipMgr.setPrimaryClip(clip);
}
mClipMgr.addPrimaryClipChangedListener(this);
}

View File

@@ -276,7 +276,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
int buttonState = (event.getButtonState() >> 4) | (1 << (toolType == MotionEvent.TOOL_TYPE_STYLUS ? 0 : 30));
SDLActivity.onNativePen(pointerId, buttonState, action, x, y, p);
} else if (toolType == MotionEvent.TOOL_TYPE_FINGER) {
} else { // MotionEvent.TOOL_TYPE_FINGER or MotionEvent.TOOL_TYPE_UNKNOWN
pointerId = event.getPointerId(i);
x = getNormalizedX(event.getX(i));
y = getNormalizedY(event.getY(i));

View File

@@ -542,6 +542,7 @@ class AndroidApiVersion:
def __repr__(self) -> str:
return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>"
ANDROID_ABI_EXTRA_LINK_OPTIONS = {}
class Releaser:
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
@@ -1013,6 +1014,7 @@ class Releaser:
android_devel_file_tree = ArchiveFileTree()
for android_abi in android_abis:
extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "")
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
build_dir = self.root / "build-android" / f"{android_abi}-build"
install_dir = self.root / "install-android" / f"{android_abi}-install"
@@ -1023,8 +1025,11 @@ class Releaser:
"cmake",
"-S", str(self.root),
"-B", str(build_dir),
f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
# NDK 21e does not support -ffile-prefix-map
# f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
# f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}",
f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}",
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
@@ -1530,7 +1535,7 @@ def main(argv=None) -> int:
parser.error("Invalid --android-api, and/or could not be detected")
android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}"
if not android_api_path.is_dir():
parser.error(f"Android API directory does not exist ({android_api_path})")
logger.warning(f"Android API directory does not exist ({android_api_path})")
with section_printer.group("Android arguments"):
print(f"android_home = {args.android_home}")
print(f"android_ndk_home = {args.android_ndk_home}")

View File

@@ -0,0 +1,127 @@
#!/bin/bash
progname="${0##*/}"
progname="${progname%.sh}"
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
cleanup_trap() {
if [ -n "${tmp}" -a -d "${tmp}" ]; then
rm -rf ${tmp}
fi
exit $1
}
usage() {
echo "Host side script to check the ELF alignment of shared libraries."
echo "Shared libraries are reported ALIGNED when their ELF regions are"
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
echo
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
}
if [ ${#} -ne 1 ]; then
usage
exit
fi
case ${1} in
--help | -h | -\?)
usage
exit
;;
*)
dir="${1}"
;;
esac
if ! [ -f "${dir}" -o -d "${dir}" ]; then
echo "Invalid file: ${dir}" >&2
exit 1
fi
if [[ "${dir}" == *.apk ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
echo "=== APK zip-alignment ==="
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
echo "========================="
else
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
echo " You can install the latest build-tools by running the below command"
echo " and updating your \$PATH:"
echo
echo " sdkmanager \"build-tools;35.0.0-rc3\""
fi
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
dir="${tmp}"
fi
if [[ "${dir}" == *.apex ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
dir="${tmp}"
fi
RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"
unaligned_libs=()
unaligned_critical_libs=()
echo
echo "=== ELF alignment ==="
matches="$(find "${dir}" -type f)"
IFS=$'\n'
for match in $matches; do
# We could recursively call this script or rewrite it to though.
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
[[ $(file "${match}") == *"ELF"* ]] || continue
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
else
unaligned_libs+=("${match}")
# Check if this is a critical architecture (arm64-v8a or x86_64)
if [[ "${match}" == *"arm64-v8a"* ]] || [[ "${match}" == *"x86_64"* ]]; then
unaligned_critical_libs+=("${match}")
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
else
echo -e "${match}: UNALIGNED ($res)"
fi
fi
done
if [ ${#unaligned_libs[@]} -gt 0 ]; then
echo -e "Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
fi
echo "====================="
# Exit with appropriate code: 1 if critical unaligned libs found, 0 otherwise
if [ ${#unaligned_critical_libs[@]} -gt 0 ]; then
echo -e "${RED}Found ${#unaligned_critical_libs[@]} critical unaligned libs.${ENDCOLOR}"
exit 1
else
echo -e "${GREEN}ELF Verification Successful${ENDCOLOR}"
exit 0
fi

View File

@@ -161,6 +161,7 @@ def find_symbols_in_file(file: pathlib.Path) -> int:
"src/libm",
"src/hidapi",
"src/video/khronos",
"src/video/stb_image.h",
"include/SDL3",
"build-scripts/gen_audio_resampler_filter.c",
"build-scripts/gen_audio_channel_conversion.c",

View File

@@ -183,7 +183,7 @@
],
"api-minimum": 21,
"api-target": 35,
"ndk-minimum": 21,
"ndk-minimum": 28,
"aar-files": {
"": [
"android-project/app/proguard-rules.pro:proguard.txt",

View File

@@ -1,21 +0,0 @@
#!/bin/sh
#
# libtool assumes that the compiler can handle the -fPIC flag
# This isn't always true (for example, nasm can't handle it)
command=""
while [ $# -gt 0 ]; do
case "$1" in
-?PIC)
# Ignore -fPIC and -DPIC options
;;
-fno-common)
# Ignore -fPIC and -DPIC options
;;
*)
command="$command $1"
;;
esac
shift
done
echo $command
exec $command

View File

@@ -424,7 +424,11 @@ sub dewikify_chunk {
$str .= "\n```$codelang\n$code\n```\n";
}
} elsif ($dewikify_mode eq 'manpage') {
$str =~ s/\./\\[char46]/gms; # make sure these can't become control codes.
# make sure these can't become part of roff syntax.
$str =~ s/\./\\[char46]/gms;
$str =~ s/"/\\(dq/gms;
$str =~ s/'/\\(aq/gms;
if ($wikitype eq 'mediawiki') {
# Dump obvious wikilinks.
if (defined $apiprefixregex) {
@@ -449,33 +453,52 @@ sub dewikify_chunk {
# bullets
$str =~ s/^\* /\n\\\(bu /gm;
} elsif ($wikitype eq 'md') {
# bullets
$str =~ s/^\- /\n\\(bu /gm;
# merge paragraphs
$str =~ s/^[ \t]+//gm;
$str =~ s/([^\-\n])\n([^\-\n])/$1 $2/g;
$str =~ s/\n\n/\n.PP\n/g;
# Dump obvious wikilinks.
if (defined $apiprefixregex) {
$str =~ s/\[(\`?$apiprefixregex[a-zA-Z0-9_]+\`?)\]\($apiprefixregex[a-zA-Z0-9_]+\)/\n.BR $1\n/gms;
my $apr = $apiprefixregex;
if(!($apr =~ /\A\(.*\)\Z/s)) {
# we're relying on the apiprefixregex having a capturing group.
$apr = "(" . $apr . ")";
}
$str =~ s/(\S*?)\[\`?($apr[a-zA-Z0-9_]+)\`?\]\($apr[a-zA-Z0-9_]+\)(\S*)\s*/\n.BR "" "$1" "$2" "$5"\n/gm;
# handle cases like "[x](x), [y](y), [z](z)" being separated.
while($str =~ s/(\.BR[^\n]*)\n\n\.BR/$1\n.BR/gm) {}
}
# links
$str =~ s/\[(.*?)]\((https?\:\/\/.*?)\)/\n.URL "$2" "$1"\n/g;
# <code></code> is also popular. :/
$str =~ s/\s*\`(.*?)\`\s*/\n.BR $1\n/gms;
$str =~ s/\s*(\S*?)\`([^\n]*?)\`(\S*)\s*/\n.BR "" "$1" "$2" "$3"\n/gms;
# bold+italic (this looks bad, just make it bold).
$str =~ s/\s*\*\*\*(.*?)\*\*\*\s*/\n.B $1\n/gms;
$str =~ s/\s*(\S*?)\*\*\*([^\n]*?)\*\*\*(\S*)\s*/\n.BR "" "$1" "$2" "$3"\n/gms;
# bold
$str =~ s/\s*\*\*(.*?)\*\*\s*/\n.B $1\n/gms;
$str =~ s/\s*(\S*?)\*\*([^\n]*?)\*\*(\S*)\s*/\n.BR "" "$1" "$2" "$3"\n/gms;
# italic
$str =~ s/\s*\*(.*?)\*\s*/\n.I $1\n/gms;
# bullets
$str =~ s/^\- /\n\\\(bu /gm;
$str =~ s/\s*(\S*?)\*([^\n]*?)\*(\S*)\s*/\n.IR "" "$1" "$2" "$3"\n/gms;
}
# cleanup unnecessary quotes
$str =~ s/(\.[IB]R?)(.*?) ""\n/$1$2\n/gm;
$str =~ s/(\.[IB]R?) "" ""(.*?)\n/$1$2\n/gm;
$str =~ s/"(\S+)"/$1/gm;
# cleanup unnecessary whitespace
$str =~ s/ +\n/\n/gm;
if (defined $code) {
$code =~ s/\A\n+//gms;
$code =~ s/\n+\Z//gms;
$code =~ s/\\/\\(rs/gms;
if ($dewikify_manpage_code_indent) {
$str .= "\n.IP\n"
} else {
@@ -580,7 +603,7 @@ sub dewikify {
$retval .= dewikify_chunk($wikitype, $1, $2, $3);
}
} elsif ($wikitype eq 'md') {
while ($str =~ s/\A(.*?)\n```(.*?)\n(.*?)\n```\n//ms) {
while ($str =~ s/\A(.*?)\n?```(.*?)\n(.*?)\n```\n//ms) {
$retval .= dewikify_chunk($wikitype, $1, $2, $3);
}
}
@@ -2765,7 +2788,6 @@ __EOF__
my $wikitype = $wikitypes{$sym};
my $sectionsref = $wikisyms{$sym};
my $remarks = $sectionsref->{'Remarks'};
my $params = $sectionsref->{'Function Parameters'};
my $returns = $sectionsref->{'Return Value'};
my $version = $sectionsref->{'Version'};
my $threadsafety = $sectionsref->{'Thread Safety'};
@@ -2773,6 +2795,23 @@ __EOF__
my $examples = $sectionsref->{'Code Examples'};
my $deprecated = $sectionsref->{'Deprecated'};
my $headerfile = $manpageheaderfiletext;
my $params = undef;
if ($symtype == -1) { # category documentation block.
# nothing to be done here.
} elsif (($symtype == 1) || (($symtype == 5))) { # we'll assume a typedef (5) with a \param is a function pointer typedef.
$params = $sectionsref->{'Function Parameters'};
} elsif ($symtype == 2) {
$params = $sectionsref->{'Macro Parameters'};
} elsif ($symtype == 3) {
$params = $sectionsref->{'Fields'};
} elsif ($symtype == 4) {
$params = $sectionsref->{'Values'};
} else {
die("Unexpected symtype $symtype");
}
$headerfile =~ s/\%fname\%/$headersymslocation{$sym}/g;
$headerfile .= "\n";
@@ -2839,18 +2878,22 @@ __EOF__
$str .= dewikify($wikitype, $deprecated) . "\n";
}
my $incfile = $mainincludefname;
if (defined $headerfile) {
$str .= ".SH HEADER FILE\n";
$str .= dewikify($wikitype, $headerfile) . "\n";
if($headerfile =~ /Defined in (.*)/) {
$incfile = $1;
}
}
$str .= ".SH SYNOPSIS\n";
$str .= ".nf\n";
$str .= ".B #include \\(dq$mainincludefname\\(dq\n";
$str .= ".B #include <$incfile>\n";
$str .= ".PP\n";
my @decllines = split /\n/, $decl;
foreach (@decllines) {
$_ =~ s/\\/\\(rs/g; # fix multiline macro defs
$_ =~ s/"/\\(dq/g;
$str .= ".BI \"$_\n";
}
$str .= ".fi\n";
@@ -2938,8 +2981,11 @@ __EOF__
}
if (defined $returns) {
# Chop datatype in parentheses off the front.
if(!($returns =~ s/\A\([^\[]*\[[^\]]*\]\([^\)]*\)[^\)]*\) //ms)) {
$returns =~ s/\A\([^\)]*\) //ms;
}
$returns = dewikify($wikitype, $returns);
$returns =~ s/\A\(.*?\)\s*//; # Chop datatype in parentheses off the front.
$str .= ".SH RETURN VALUE\n";
$str .= "$returns\n";
}
@@ -2975,6 +3021,8 @@ __EOF__
s/\A\/*//;
s/\A\.BR\s+//; # dewikify added this, but we want to handle it.
s/\A\.I\s+//; # dewikify added this, but we want to handle it.
s/\A\.PP\s*//; # dewikify added this, but we want to handle it.
s/\\\(bu//; # dewikify added this, but we want to handle it.
s/\A\s*[\:\*\-]\s*//;
s/\A\s+//;
s/\s+\Z//;

View File

@@ -77,6 +77,9 @@ else()
endif()
endif()
if(NOT SDL3_COMPONENTS AND NOT TARGET SDL3::Headers AND NOT TARGET SDL3::SDL3-shared AND NOT TARGET SDL3::SDL3-static)
set(SDL3_FOUND FALSE)
endif()
check_required_components(SDL3)
function(_sdl_create_target_alias_compat NEW_TARGET TARGET)
@@ -93,7 +96,7 @@ endfunction()
if(NOT TARGET SDL3::SDL3)
if(TARGET SDL3::SDL3-shared)
_sdl_create_target_alias_compat(SDL3::SDL3 SDL3::SDL3-shared)
else()
elseif(TARGET SDL3::SDL3-static)
_sdl_create_target_alias_compat(SDL3::SDL3 SDL3::SDL3-static)
endif()
endif()

View File

@@ -823,7 +823,7 @@ macro(CheckPTHREAD)
if(CMAKE_C_COMPILER_ID MATCHES "SunPro")
set(PTHREAD_LDFLAGS "-mt -lpthread")
else()
set(PTHREAD_LDFLAGS "-pthread -lposix4")
set(PTHREAD_LDFLAGS "-pthread")
endif()
elseif(SYSV5)
set(PTHREAD_CFLAGS "-D_REENTRANT -Kthread")
@@ -1077,6 +1077,14 @@ endmacro()
# Check for HIDAPI support
macro(CheckHIDAPI)
if(ANDROID)
enable_language(CXX)
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/android/hid.cpp")
endif()
if(IOS OR TVOS)
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/ios/hid.m")
set(SDL_FRAMEWORK_COREBLUETOOTH 1)
endif()
if(SDL_HIDAPI)
set(HAVE_HIDAPI ON)
if(SDL_HIDAPI_LIBUSB)
@@ -1109,14 +1117,6 @@ macro(CheckHIDAPI)
endif()
if(HAVE_HIDAPI)
if(ANDROID)
enable_language(CXX)
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/android/hid.cpp")
endif()
if(IOS OR TVOS)
sdl_sources("${SDL3_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)

View File

@@ -160,3 +160,63 @@ function(SDL_AddCommonCompilerFlags TARGET)
endif()
endif()
endfunction()
function(check_x86_source_compiles BODY VAR)
if(ARGN)
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
endif()
if(APPLE_MULTIARCH AND (SDL_CPU_X86 OR SDL_CPU_X64))
set(test_conditional 1)
else()
set(test_conditional 0)
endif()
check_c_source_compiles("
#if ${test_conditional}
# if defined(__i386__) || defined(__x86_64__)
# define test_enabled 1
# else
# define test_enabled 0 /* feign success in Apple multi-arch configs */
# endif
#else /* test normally */
# define test_enabled 1
#endif
#if test_enabled
${BODY}
#else
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
return 0;
}
#endif" ${VAR})
endfunction()
function(check_arm_source_compiles BODY VAR)
if(ARGN)
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
endif()
if(APPLE_MULTIARCH AND (SDL_CPU_ARM32 OR SDL_CPU_ARM64))
set(test_conditional 1)
else()
set(test_conditional 0)
endif()
check_c_source_compiles("
#if ${test_conditional}
# if defined(__arm__) || defined(__aarch64__)
# define test_enabled 1
# else
# define test_enabled 0 /* feign success in Apple multi-arch configs */
# endif
#else /* test normally */
# define test_enabled 1
#endif
#if test_enabled
${BODY}
#else
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
return 0;
}
#endif" ${VAR})
endfunction()

View File

@@ -4,15 +4,15 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
foreach(known_arch IN LISTS known_archs)
set(SDL_CPU_${known_arch} "0")
set(SDL_CPU_${known_arch} "0" PARENT_SCOPE)
endforeach()
set(detected_archs)
foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
if(osx_arch STREQUAL "x86_64")
set(SDL_CPU_X64 "1")
set(SDL_CPU_X64 "1" PARENT_SCOPE)
list(APPEND detected_archs "X64")
elseif(osx_arch STREQUAL "arm64")
set(SDL_CPU_ARM64 "1")
set(SDL_CPU_ARM64 "1" PARENT_SCOPE)
list(APPEND detected_archs "ARM64")
endif()
endforeach()

View File

@@ -5,7 +5,12 @@ The easiest way to use SDL is to include it as a subproject in your project.
We'll start by creating a simple project to build and run [hello.c](hello.c)
Create the file CMakeLists.txt
# Get a copy of the SDL source:
```sh
git clone https://github.com/libsdl-org/SDL.git vendored/SDL
```
# Create the file CMakeLists.txt
```cmake
cmake_minimum_required(VERSION 3.16)
project(hello)
@@ -25,24 +30,26 @@ add_executable(hello WIN32 hello.c)
target_link_libraries(hello PRIVATE SDL3::SDL3)
```
Build:
# Configure and Build:
```sh
cmake -S . -B build
cmake --build build
```
Run:
- On Windows the executable is in the build Debug directory:
```sh
cd build/Debug
./hello
```
- On other platforms the executable is in the build directory:
# Run:
The executable should be in the `build` directory:
```sh
cd build
./hello
```
If there wasn't an executable there despite the above Build section running successfully, it's likely because you're following this guide using the Visual Studio toolchain, it should instead be in the `build/Debug` directory:
```sh
cd build/Debug
./hello
```
A more complete example is available at:
https://github.com/Ravbug/sdl3-sample

95
docs/INTRO-mingw.md Normal file
View File

@@ -0,0 +1,95 @@
# Introduction to SDL with MinGW
Without getting deep into the history, MinGW is a long running project that aims to bring gcc to Windows. That said, there's many distributions, versions, and forks floating around. We recommend installing [MSYS2](https://www.msys2.org/), as it's the easiest way to get a modern toolchain with a package manager to help with dependency management. This would allow you to follow the MSYS2 section below.
Otherwise you'll want to follow the "Other Distributions" section below.
We'll start by creating a simple project to build and run [hello.c](hello.c).
# MSYS2
Open the `MSYS2 UCRT64` prompt and then ensure you've installed the following packages. This will get you working toolchain, CMake, Ninja, and of course SDL3.
```sh
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-sdl3
```
## Create the file CMakeLists.txt
```cmake
cmake_minimum_required(VERSION 3.26)
project(hello C CXX)
find_package(SDL3 REQUIRED)
add_executable(hello)
target_sources(hello
PRIVATE
hello.c
)
target_link_libraries(hello SDL3::SDL3)
```
## Configure and Build:
```sh
cmake -S . -B build
cmake --build build
```
## Run:
The executable is in the `build` directory:
```sh
cd build
./hello
```
# Other Distributions
Things can get quite complicated with other distributions of MinGW. If you can't follow [the cmake intro](INTRO-cmake.md), perhaps due to issues getting cmake to understand your toolchain, this section should work.
## Acquire SDL
Download the `SDL3-devel-<version>-mingw.zip` asset from [the latest release.](https://github.com/libsdl-org/SDL/releases/latest) Then extract it inside your project folder such that the output of `ls SDL3-<version>` looks like `INSTALL.md LICENSE.txt Makefile README.md cmake i686-w64-mingw32 x86_64-w64-mingw32`.
## Know your Target Architecture
It is not uncommon for folks to not realize their distribution is targeting 32bit Windows despite things like the name of the toolchain, or the fact that they're running on a 64bit system. We'll ensure we know up front what we need:
Create a file named `arch.c` with the following contents:
```c
#include <stddef.h>
#include <stdio.h>
int main() {
#if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
size_t ptr_size = sizeof(int*);
if (4 == ptr_size) puts("i686-w64-mingw32");
else if (8 == ptr_size) puts("x86_64-w64-mingw32");
else puts("Unknown Architecture");
#else
puts("Unknown Architecture");
#endif
return 0;
}
```
Then run
```sh
gcc arch.c
./a.exe
```
This should print out which library directory we'll need to use when compiling, keep this value in mind, you'll need to use it when compiling in the next section as `<arch>`. If you get "Unknown Architecture" please [report a bug](https://github.com/libsdl-org/SDL/issues).
## Build and Run
Now we should have everything needed to compile and run our program. You'll need to ensure to replace `<version>` with the version of the release of SDL3 you downloaded, as well as use the `<arch>` we learned in the previous section.
```sh
gcc hello.c -o hello.exe -I SDL3-<version>/<arch>/include -L SDL3-<version>/<arch>/lib -lSDL3 -mwindows
cp SDL3-<version>/<arch>/bin/SDL3.dll SDL3.dll
./hello.exe
```

View File

@@ -5,10 +5,12 @@ The easiest way to use SDL is to include it as a subproject in your project.
We'll start by creating a simple project to build and run [hello.c](hello.c)
- Get a copy of the SDL source, you can clone the repo, or download the "Source Code" asset from [the latest release.](https://github.com/libsdl-org/SDL/releases/latest)
- If you've downloaded a release, make sure to extract the contents somewhere you can find it.
- Create a new project in Visual Studio, using the C++ Empty Project template
- Add hello.c to the Source Files
- Right click the solution, select add an existing project, navigate to VisualC/SDL and add SDL.vcxproj
- Select your main project and go to Project -> Add Reference and select SDL3
- Select your main project and go to Project -> Properties, set the filter at the top to "All Configurations" and "All Platforms", select VC++ Directories and add the SDL include directory to "Include Directories"
- Right click the solution, select add an existing project, navigate to `VisualC/SDL` from within the source you cloned or downloaded above and add SDL.vcxproj
- Select your main project and go to Project -> Add -> Reference and select SDL3
- Select your main project and go to Project -> Properties, set the filter at the top to "All Configurations" and "All Platforms", select C/C++ -> General and add the SDL include directory to "Additional Include Directories"
- Build and run!

View File

@@ -242,7 +242,7 @@ not give you any processing time after the events are delivered.
e.g.
int HandleAppEvents(void *userdata, SDL_Event *event)
bool HandleAppEvents(void *userdata, SDL_Event *event)
{
switch (event->type)
{
@@ -250,12 +250,12 @@ e.g.
/* Terminate the app.
Shut everything down before returning from this function.
*/
return 0;
return false;
case SDL_EVENT_LOW_MEMORY:
/* You will get this when your app is paused and iOS wants more memory.
Release as much memory as possible.
*/
return 0;
return false;
case SDL_EVENT_WILL_ENTER_BACKGROUND:
/* Prepare your app to go into the background. Stop loops, etc.
This gets called when the user hits the home button, or gets a call.
@@ -264,15 +264,15 @@ e.g.
in addition, you should set the render target to NULL, if you're using
it, e.g. call SDL_SetRenderTarget(renderer, NULL).
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_BACKGROUND:
/* Your app is NOT active at this point. */
return 0;
return false;
case SDL_EVENT_WILL_ENTER_FOREGROUND:
/* This call happens when your app is coming back to the foreground.
Restore all your state here.
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_FOREGROUND:
/* Restart your loops here.
Your app is interactive and getting CPU again.
@@ -283,10 +283,10 @@ e.g.
event SDL_EVENT_RENDER_DEVICE_RESET and recreate your OpenGL context and
restore your textures when you get it, or quit the app.
*/
return 0;
return false;
default:
/* No special processing, add it to the event queue */
return 1;
return true;
}
}

View File

@@ -1,32 +1,6 @@
SDL 3.0 has new support for high DPI displays. Interfaces provided by SDL uses the platform's native coordinates unless otherwise specified.
To reconcile platform differences in their approach to high-density scaling, SDL provides the following interfaces:
- `SDL_GetWindowSize()` retrieves the window dimensions in native coordinates.
- `SDL_GetWindowSizeInPixels()` retrieves the window dimensions in pixels-addressable.
- `SDL_GetDisplayContentScale()` retrieves the suggested amplification factor when drawing in native coordinates.
- `SDL_GetWindowDisplayScale()` retrieves the suggested amplification factor when drawing in pixels-addressable.
- `SDL_GetWindowPixelDensity()` retrieves how many addressable pixels correspond to one unit of native coordinates.
- `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` is emitted when the value retrievable from `SDL_GetWindowSizeInPixels()` changes.
- `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` is emitted when the value retrievable from `SDL_GetWindowDisplayScale()` changes.
- Windows created with `SDL_WINDOW_HIGH_PIXEL_DENSITY` will ask the platform to display addressable pixels at their natural scale.
## Numeric example
Given a fullscreen window spanning a 3840x2160 monitor set to 2x display or 200% scaling, the following tabulates the effect of creating a window with or without `SDL_WINDOW_HIGH_PIXEL_DENSITY` on MacOS and Win32:
| Value | MacOS (Default) | MacOS (HD) | Win32 (Default & HD) |
|--------------------------------|-----------------|------------|----------------------|
| `SDL_GetWindowSize()` | 1920x1080 | 1920x1080 | 3840x2160 |
| `SDL_GetWindowSizeInPixels()` | 1920x1080 | 3840x2160 | 3840x2160 |
| `SDL_GetDisplayContentScale()` | 1.0 | 1.0 | 2.0 |
| `SDL_GetWindowDisplayScale()` | 1.0 | 2.0 | 2.0 |
| `SDL_GetWindowPixelDensity()` | 1.0 | 2.0 | 1.0 |
Observe the philosophical difference between the approaches taken by MacOS and Win32:
- Win32 coordinate system always deals in physical device pixels, high DPI support is achieved by providing an advisory hint for the developer to enlarge drawn objects. Ignoring the advisory scale factor results in graphics appearing tiny.
- MacOS coordinate system always deals in physical content sizes, high DPI support is achieved by providing an optional flag for the developer to request finer granularity. Omitting the granularity request results in graphics appearing coarse.
## Explanation
Displays now have a content display scale, which is the expected scale for content based on the DPI settings of the display. For example, a 4K display might have a 2.0 (200%) display scale, which means that the user expects UI elements to be twice as big on this display, to aid in readability. You can query the display content scale using `SDL_GetDisplayContentScale()`, and when this changes you get an `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` event.
@@ -34,3 +8,33 @@ Displays now have a content display scale, which is the expected scale for conte
The window size is now distinct from the window pixel size, and the ratio between the two is the window pixel density. If the window is created with the `SDL_WINDOW_HIGH_PIXEL_DENSITY` flag, SDL will try to match the native pixel density for the display, otherwise it will try to have the pixel size match the window size. You can query the window pixel density using `SDL_GetWindowPixelDensity()`. You can query the window pixel size using `SDL_GetWindowSizeInPixels()`, and when this changes you get an `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` event. You are guaranteed to get a `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` event when a window is created and resized, and you can use this event to create and resize your graphics context for the window.
The window has a display scale, which is the scale from the pixel resolution to the desired content size, e.g. the combination of the pixel density and the content scale. For example, a 3840x2160 window displayed at 200% on Windows, and a 1920x1080 window with the high density flag on a 2x display on macOS will both have a pixel size of 3840x2160 and a display scale of 2.0. You can query the window display scale using `SDL_GetWindowDisplayScale()`, and when this changes you get an `SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED` event.
## Numeric example
Given a window spanning a 3840x2160 monitor set to 2x display or 200% scaling, the following tabulates the effect of creating a window with or without `SDL_WINDOW_HIGH_PIXEL_DENSITY` on macOS and Windows:
| Value | macOS (Default) | macOS (HD) | Windows (Default & HD) |
|--------------------------------|-----------------|------------|------------------------|
| `SDL_GetWindowSize()` | 1920x1080 | 1920x1080 | 3840x2160 |
| `SDL_GetWindowSizeInPixels()` | 1920x1080 | 3840x2160 | 3840x2160 |
| `SDL_GetDisplayContentScale()` | 1.0 | 1.0 | 2.0 |
| `SDL_GetWindowDisplayScale()` | 1.0 | 2.0 | 2.0 |
| `SDL_GetWindowPixelDensity()` | 1.0 | 2.0 | 1.0 |
Observe the difference between the approaches taken by macOS and Windows:
- The Windows and Android coordinate system always deals in physical device pixels, high DPI support is achieved by providing a content scale that tells the developer to draw objects larger. Ignoring this scale factor results in graphics appearing tiny.
- The macOS and iOS coordinate system always deals in window coordinates, high DPI support is achieved by providing an optional flag for the developer to request more pixels. Omitting this flag results in graphics having low detail.
- On Linux, X11 uses a similar approach to Windows and Wayland uses a similar approach to macOS.
## Solution
Proper high DPI support takes into account both the content scale and the pixel density.
First, you'd create your window with the `SDL_WINDOW_HIGH_PIXEL_DENSITY` flag, assuming you want the highest detail possible. Then you'd get the window display scale to see how much your UI elements should be enlarged to be readable.
If you're using the SDL 2D renderer, SDL provides the function `SDL_ConvertEventToRenderCoordinates()` to convert mouse coordinates between window coordinates and rendering coordinates, and the more general functions `SDL_RenderCoordinatesFromWindow()` and `SDL_RenderCoordinatesToWindow()` to do other conversion between them.
If you're not using the 2D renderer, you can implement this yourself using `SDL_GetWindowPixelDensity()` as scale factor to convert from window coordinates to pixels.
Finally you'll want to test on both Windows and macOS if possible to make sure your high DPI support works in all environments.

View File

@@ -65,7 +65,7 @@ not give you any processing time after the events are delivered.
e.g.
int HandleAppEvents(void *userdata, SDL_Event *event)
bool HandleAppEvents(void *userdata, SDL_Event *event)
{
switch (event->type)
{
@@ -73,37 +73,37 @@ e.g.
/* Terminate the app.
Shut everything down before returning from this function.
*/
return 0;
return false;
case SDL_EVENT_LOW_MEMORY:
/* You will get this when your app is paused and iOS wants more memory.
Release as much memory as possible.
*/
return 0;
return false;
case SDL_EVENT_WILL_ENTER_BACKGROUND:
/* Prepare your app to go into the background. Stop loops, etc.
This gets called when the user hits the home button, or gets a call.
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_BACKGROUND:
/* This will get called if the user accepted whatever sent your app to the background.
If the user got a phone call and canceled it, you'll instead get an SDL_EVENT_DID_ENTER_FOREGROUND event and restart your loops.
When you get this, you have 5 seconds to save all your state or the app will be terminated.
Your app is NOT active at this point.
*/
return 0;
return false;
case SDL_EVENT_WILL_ENTER_FOREGROUND:
/* This call happens when your app is coming back to the foreground.
Restore all your state here.
*/
return 0;
return false;
case SDL_EVENT_DID_ENTER_FOREGROUND:
/* Restart your loops here.
Your app is interactive and getting CPU again.
*/
return 0;
return false;
default:
/* No special processing, add it to the event queue */
return 1;
return true;
}
}

View File

@@ -19,7 +19,7 @@ Ubuntu 18.04, all available features enabled:
libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev \
libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev \
libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev
libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev
Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev liburing-dev` to that command line.
@@ -28,7 +28,7 @@ Fedora 35, all available features enabled:
sudo yum install gcc git-core make cmake \
alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \
libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \
libXi-devel libXScrnSaver-devel dbus-devel ibus-devel fcitx-devel \
libXi-devel libXScrnSaver-devel dbus-devel ibus-devel \
systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \
mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \
libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \
@@ -45,6 +45,10 @@ openSUSE Tumbleweed:
sudo zypper in libunwind-devel libusb-1_0-devel Mesa-libGL-devel libxkbcommon-devel libdrm-devel \
libgbm-devel pipewire-devel libpulse-devel sndio-devel Mesa-libEGL-devel
Arch:
sudo pacman -S alsa-lib cmake hidapi ibus jack libdecor libgl libpulse libusb libx11 libxcursor libxext libxinerama libxkbcommon libxrandr libxrender libxss mesa ninja pipewire sndio vulkan-driver vulkan-headers wayland wayland-protocols
Joystick does not work
--------------------------------------------------------------------------------

View File

@@ -49,7 +49,7 @@ NSApplicationDelegate implementation:
```objc
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
if (SDL_GetEventState(SDL_EVENT_QUIT) == SDL_ENABLE) {
if (SDL_EventEnabled(SDL_EVENT_QUIT)) {
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_QUIT;
@@ -61,7 +61,7 @@ NSApplicationDelegate implementation:
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
if (SDL_GetEventState(SDL_EVENT_DROP_FILE) == SDL_ENABLE) {
if (SDL_EventEnabled(SDL_EVENT_DROP_FILE)) {
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_DROP_FILE;

View File

@@ -411,7 +411,7 @@ The iscapture field of SDL_AudioDeviceEvent has been renamed recording.
SDL_QUERY, SDL_IGNORE, SDL_ENABLE, and SDL_DISABLE have been removed. You can use the functions SDL_SetEventEnabled() and SDL_EventEnabled() to set and query event processing state.
SDL_AddEventWatch() now returns SDL_FALSE_ if it fails because it ran out of memory and couldn't add the event watch callback.
SDL_AddEventWatch() now returns false if it fails because it ran out of memory and couldn't add the event watch callback.
SDL_RegisterEvents() now returns 0 if it couldn't allocate any user events.

View File

@@ -11,7 +11,7 @@
- [macOS](README-macos.md)
- [NetBSD](README-bsd.md)
- [Nintendo Switch](README-switch.md)
- [Nintendo 3DS](README-3ds.md)
- [Nintendo 3DS](README-n3ds.md)
- [OpenBSD](README-bsd.md)
- [PlayStation 2](README-ps2.md)
- [PlayStation 4](README-ps4.md)

View File

@@ -29,7 +29,7 @@ cmake --install build
## Compiling a HelloWorld
[PSP Hello World](https://psp-dev.org/doku.php?id=tutorial:hello_world)
[PSP Hello World](https://pspdev.github.io/basic_programs.html#hello-world)
## To Do
- PSP Screen Keyboard

View File

@@ -1,60 +1,48 @@
# Versioning
## Since 2.23.0
## Since 3.2.0
SDL follows an "odd/even" versioning policy, similar to GLib, GTK, Flatpak
and older versions of the Linux kernel:
* The major version (first part) increases when backwards compatibility
is broken, which will happen infrequently.
* If the minor version (second part) is divisible by 2
(for example 2.24.x, 2.26.x), this indicates a version of SDL that
is believed to be stable and suitable for production use.
* If the minor version (second part) and the patch version (third part) is
divisible by 2 (for example 3.2.6, 3.4.0), this indicates a version of
SDL that is believed to be stable and suitable for production use.
* In stable releases, the patchlevel or micro version (third part)
indicates bugfix releases. Bugfix releases should not add or
remove ABI, so the ".0" release (for example 2.24.0) should be
forwards-compatible with all the bugfix releases from the
same cycle (for example 2.24.1).
indicates bugfix releases. Bugfix releases may add small changes
to the ABI, so newer patch versions are backwards-compatible but
not fully forwards-compatible. For example, programs built against
SDL 3.2.0 should work fine with SDL 3.2.8, but programs built against
SDL 3.2.8 may not work with 3.2.0.
* The minor version increases when new API or ABI is added, or when
other significant changes are made. Newer minor versions are
backwards-compatible, but not fully forwards-compatible.
For example, programs built against SDL 2.24.x should work fine
with SDL 2.26.x, but programs built against SDL 2.26.x will not
necessarily work with 2.24.x.
* The minor version increases when significant changes are made that
require longer development or testing time, e.g. major new functionality,
or revamping support for a platform. Newer minor versions are
backwards-compatible, but not fully forwards-compatible. For example,
programs built against SDL 3.2.x should work fine with SDL 3.4.x,
but programs built against SDL 3.4.x may not work with 3.2.x.
* If the minor version (second part) is not divisible by 2
(for example 2.23.x, 2.25.x), this indicates a development prerelease
of SDL that is not suitable for stable software distributions.
* If the minor version (second part) or patch version (third part) is not
divisible by 2 (for example 3.2.9, 3.3.x), this indicates a development
prerelease of SDL that is not suitable for stable software distributions.
Use with caution.
* The patchlevel or micro version (third part) increases with
each prerelease.
* Each prerelease might add new API and/or ABI.
* The patchlevel or micro version (third part) increases with each prerelease.
* Prereleases are backwards-compatible with older stable branches.
For example, 2.25.x will be backwards-compatible with 2.24.x.
For example, programs built against SDL 3.2.x should work fine with
SDL 3.3.x, but programs built against SDL 3.3.x may not work with 3.2.x.
* Prereleases are not guaranteed to be backwards-compatible with
each other. For example, new API or ABI added in 2.25.1
might be removed or changed in 2.25.2.
If this would be a problem for you, please do not use prereleases.
* Prereleases are not guaranteed to be backwards-compatible with each other.
For example, new API or ABI added in 3.3.0 might be removed or changed in
3.3.1. If this would be a problem for you, please do not use prereleases.
* Only upgrade to a prerelease if you can guarantee that you will
promptly upgrade to the stable release that follows it.
For example, do not upgrade to 2.23.x unless you will be able to
upgrade to 2.24.0 when it becomes available.
* Only use a prerelease if you can guarantee that you will promptly upgrade
to the stable release that follows it. For example, do not use 3.3.x
unless you will be able to upgrade to 3.4.0 when it becomes available.
* Software distributions that have a freeze policy (in particular Linux
distributions with a release cycle, such as Debian and Fedora)
should usually only package stable releases, and not prereleases.
should only package stable releases, and not prereleases.
## Before 2.23.0
Older versions of SDL followed a similar policy, but instead of the
odd/even rule applying to the minor version, it applied to the patchlevel
(micro version, third part). For example, 2.0.22 was a stable release
and 2.0.21 was a prerelease.

View File

@@ -59,6 +59,10 @@ encounter limitations or behavior that is different from other windowing systems
`SDL_APP_ID` hint string, the desktop entry file name should match the application ID. For example, if your
application ID is set to `org.my_org.sdl_app`, the desktop entry file should be named `org.my_org.sdl_app.desktop`.
### Keyboard grabs don't work when running under XWayland
- On GNOME based desktops, the dconf setting `org/gnome/mutter/wayland/xwayland-allow-grabs` must be enabled.
## Using custom Wayland windowing protocols with SDL windows
Under normal operation, an `SDL_Window` corresponds to an XDG toplevel window, which provides a standard desktop window.

View File

@@ -69,7 +69,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
A sine wave is unchanging audio--easy to stream--but for video games, you'll want
to generate significantly _less_ audio ahead of time! */
const int minimum_audio = (8000 * sizeof (float)) / 2; /* 8000 float samples per second. Half of that. */
if (SDL_GetAudioStreamAvailable(stream) < minimum_audio) {
if (SDL_GetAudioStreamQueued(stream) < minimum_audio) {
static float samples[512]; /* this will feed 512 samples each frame until we get to our maximum. */
int i;

View File

@@ -82,7 +82,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
We're being lazy here, but if there's less than the entire wav file left to play,
just shove a whole copy of it into the queue, so we always have _tons_ of
data queued for playback. */
if (SDL_GetAudioStreamAvailable(stream) < (int)wav_data_len) {
if (SDL_GetAudioStreamQueued(stream) < (int)wav_data_len) {
/* feed more data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */
SDL_PutAudioStreamData(stream, wav_data, wav_data_len);
}

View File

@@ -104,7 +104,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* If less than a full copy of the audio is queued for playback, put another copy in there.
This is overkill, but easy when lots of RAM is cheap. One could be more careful and
queue less at a time, as long as the stream doesn't run dry. */
if (SDL_GetAudioStreamAvailable(sounds[i].stream) < ((int) sounds[i].wav_data_len)) {
if (SDL_GetAudioStreamQueued(sounds[i].stream) < ((int) sounds[i].wav_data_len)) {
SDL_PutAudioStreamData(sounds[i].stream, sounds[i].wav_data, (int) sounds[i].wav_data_len);
}
}

View File

@@ -208,7 +208,7 @@ void snake_step(SnakeContext *ctx)
}
}
static int handle_key_event_(SnakeContext *ctx, SDL_Scancode key_code)
static SDL_AppResult handle_key_event_(SnakeContext *ctx, SDL_Scancode key_code)
{
switch (key_code) {
/* Quit. */
@@ -309,7 +309,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
return SDL_APP_FAILURE;
}
AppState *as = SDL_calloc(1, sizeof(AppState));
AppState *as = (AppState *)SDL_calloc(1, sizeof(AppState));
if (!as) {
return SDL_APP_FAILURE;
}

View File

@@ -156,7 +156,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
return SDL_APP_FAILURE;
}
if (!(vm = SDL_calloc(1, sizeof(*vm)))) {
if (!(vm = (BytePusher *)SDL_calloc(1, sizeof(*vm)))) {
return SDL_APP_FAILURE;
}
*(BytePusher**)appstate = vm;
@@ -199,7 +199,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
for (r = 0; r < 6; ++r) {
for (g = 0; g < 6; ++g) {
for (b = 0; b < 6; ++b, ++i) {
SDL_Color color = { r * 0x33, g * 0x33, b * 0x33, SDL_ALPHA_OPAQUE };
SDL_Color color = { (Uint8)(r * 0x33), (Uint8)(g * 0x33), (Uint8)(b * 0x33), SDL_ALPHA_OPAQUE };
palette->colors[i] = color;
}
}

View File

@@ -105,7 +105,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* draw axes as bars going across middle of screen. We don't know if it's an X or Y or whatever axis, so we can't do more than this. */
total = SDL_GetNumJoystickAxes(joystick);
y = (float) ((winh - (total * size)) / 2);
y = (winh - (total * size)) / 2;
x = ((float) winw) / 2.0f;
for (i = 0; i < total; i++) {
const SDL_Color *color = &colors[i % SDL_arraysize(colors)];
@@ -119,7 +119,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* draw buttons as blocks across top of window. We only know the button numbers, but not where they are on the device. */
total = SDL_GetNumJoystickButtons(joystick);
x = (float) ((winw - (total * size)) / 2);
x = (winw - (total * size)) / 2;
for (i = 0; i < total; i++) {
const SDL_Color *color = &colors[i % SDL_arraysize(colors)];
const SDL_FRect dst = { x, 0.0f, size, size };
@@ -136,7 +136,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* draw hats across the bottom of the screen. */
total = SDL_GetNumJoystickHats(joystick);
x = ((float) ((winw - (total * (size * 2.0f))) / 2.0f)) + (size / 2.0f);
x = ((winw - (total * (size * 2.0f))) / 2.0f) + (size / 2.0f);
y = ((float) winh) - size;
for (i = 0; i < total; i++) {
const SDL_Color *color = &colors[i % SDL_arraysize(colors)];

View File

@@ -92,8 +92,8 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* center this one and make it grow and shrink. */
dst_rect.w = (float) texture_width + (texture_width * scale);
dst_rect.h = (float) texture_height + (texture_height * scale);
dst_rect.x = ((float) (WINDOW_WIDTH - dst_rect.w)) / 2.0f;
dst_rect.y = ((float) (WINDOW_HEIGHT - dst_rect.h)) / 2.0f;
dst_rect.x = (WINDOW_WIDTH - dst_rect.w) / 2.0f;
dst_rect.y = (WINDOW_HEIGHT - dst_rect.h) / 2.0f;
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
SDL_RenderPresent(renderer); /* put it all on the screen! */

View File

@@ -141,7 +141,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* we need one more vertex, since the two triangles can share two of them. */
vertices[3].position.x = 600.0f;
vertices[3].position.y = 150.0f;
vertices[3].color.r = vertices[0].color.g = vertices[0].color.b = vertices[0].color.a = 1.0f;
vertices[3].color.r = vertices[3].color.g = vertices[3].color.b = vertices[3].color.a = 1.0f;
vertices[3].tex_coord.x = 1.0f;
vertices[3].tex_coord.y = 1.0f;

View File

@@ -20,7 +20,7 @@
*/
/**
* Main include header for the SDL library, version 3.2.4
* Main include header for the SDL library, version 3.2.24
*
* It is almost always best to include just this one header instead of
* picking out individual headers included here. There are exceptions to

View File

@@ -126,7 +126,7 @@ extern "C" {
*/
#define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner
#elif defined(_MSC_VER) && _MSC_VER >= 1310
#elif defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1310)
/* Don't include intrin.h here because it contains C++ code */
extern void __cdecl __debugbreak(void);
#define SDL_TriggerBreakpoint() __debugbreak()
@@ -149,6 +149,8 @@ extern "C" {
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" )
#elif defined(_WIN32) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__)) )
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #0xF000\n\t" )
#elif defined(__GNUC__) || defined(__clang__)
#define SDL_TriggerBreakpoint() __builtin_trap() /* older gcc may not support SDL_HAS_BUILTIN(__builtin_trap) above */
#elif defined(__386__) && defined(__WATCOMC__)
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__)
@@ -360,7 +362,7 @@ extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *
#define SDL_enabled_assert(condition) \
do { \
while ( !(condition) ) { \
static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \
static struct SDL_AssertData sdl_assert_data = { false, 0, #condition, NULL, 0, NULL, NULL }; \
const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
continue; /* go again. */ \

View File

@@ -942,7 +942,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid);
* Binding a stream to a device will set its output format for playback
* devices, and its input format for recording devices, so they match the
* device's settings. The caller is welcome to change the other end of the
* stream's format at any time with SDL_SetAudioStreamFormat().
* stream's format at any time with SDL_SetAudioStreamFormat(). If the other
* end of the stream's format has never been set (the audio stream was created
* with a NULL audio spec), this function will set it to match the device
* end's format.
*
* \param devid an audio device to bind a stream to.
* \param streams an array of audio streams to bind.
@@ -1021,7 +1024,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream);
/**
* Query an audio stream for its currently-bound device.
*
* This reports the audio device that an audio stream is currently bound to.
* This reports the logical audio device that an audio stream is currently bound to.
*
* If not bound, or invalid, this returns zero, which is not a valid device
* ID.
@@ -1717,7 +1720,7 @@ typedef void (SDLCALL *SDL_AudioStreamCallback)(void *userdata, SDL_AudioStream
* audio to the stream during this call; if needed, the request that triggered
* this callback will obtain the new data immediately.
*
* The callback's `approx_request` argument is roughly how many bytes of
* The callback's `additional_amount` argument is roughly how many bytes of
* _unconverted_ data (in the stream's input format) is needed by the caller,
* although this may overestimate a little for safety. This takes into account
* how much is already in the stream and only asks for any extra necessary to
@@ -1762,13 +1765,13 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamGetCallback(SDL_AudioStream *
* The callback can (optionally) call SDL_GetAudioStreamData() to obtain audio
* from the stream during this call.
*
* The callback's `approx_request` argument is how many bytes of _converted_
* data (in the stream's output format) was provided by the caller, although
* this may underestimate a little for safety. This value might be less than
* what is currently available in the stream, if data was already there, and
* might be less than the caller provided if the stream needs to keep a buffer
* to aid in resampling. Which means the callback may be provided with zero
* bytes, and a different amount on each call.
* The callback's `additional_amount` argument is how many bytes of
* _converted_ data (in the stream's output format) was provided by the
* caller, although this may underestimate a little for safety. This value
* might be less than what is currently available in the stream, if data was
* already there, and might be less than the caller provided if the stream
* needs to keep a buffer to aid in resampling. Which means the callback may
* be provided with zero bytes, and a different amount on each call.
*
* The callback may call SDL_GetAudioStreamAvailable to see the total amount
* currently available to read from the stream, instead of the total provided

View File

@@ -119,7 +119,7 @@ typedef struct SDL_CameraSpec
int width; /**< Frame width */
int height; /**< Frame height */
int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
int framerate_denominator; /**< Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) */
int framerate_denominator; /**< Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds) */
} SDL_CameraSpec;
/**

View File

@@ -106,7 +106,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
/**
* Get UTF-8 text from the clipboard.
*
* This functions returns an empty string if there was not enough memory left
* This function returns an empty string if there is not enough memory left
* for a copy of the clipboard's content.
*
* \returns the clipboard text on success or an empty string on failure; call
@@ -155,7 +155,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
/**
* Get UTF-8 text from the primary selection.
*
* This functions returns an empty string if there was not enough memory left
* This function returns an empty string if there is not enough memory left
* for a copy of the primary selection's content.
*
* \returns the primary selection text on success or an empty string on
@@ -194,15 +194,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
* clipboard is cleared or new data is set. The clipboard is automatically
* cleared in SDL_Quit().
*
* \param userdata a pointer to provided user data.
* \param userdata a pointer to the provided user data.
* \param mime_type the requested mime-type.
* \param size a pointer filled in with the length of the returned data.
* \returns a pointer to the data for the provided mime-type. Returning NULL
* or setting length to 0 will cause no data to be sent to the
* or setting the length to 0 will cause no data to be sent to the
* "receiver". It is up to the receiver to handle this. Essentially
* returning no data is more or less undefined behavior and may cause
* breakage in receiving applications. The returned data will not be
* freed so it needs to be retained and dealt with internally.
* freed, so it needs to be retained and dealt with internally.
*
* \since This function is available since SDL 3.2.0.
*
@@ -211,10 +211,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size);
/**
* Callback function that will be called when the clipboard is cleared, or new
* Callback function that will be called when the clipboard is cleared, or when new
* data is set.
*
* \param userdata a pointer to provided user data.
* \param userdata a pointer to the provided user data.
*
* \since This function is available since SDL 3.2.0.
*
@@ -231,7 +231,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
* respond with the data for the requested mime-type.
*
* The size of text data does not include any terminator, and the text does
* not need to be null terminated (e.g. you can directly copy a portion of a
* not need to be null-terminated (e.g., you can directly copy a portion of a
* document).
*
* \param callback a function pointer to the function that provides the
@@ -239,7 +239,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
* \param cleanup a function pointer to the function that cleans up the
* clipboard data.
* \param userdata an opaque pointer that will be forwarded to the callbacks.
* \param mime_types a list of mime-types that are being offered.
* \param mime_types a list of mime-types that are being offered. SDL copies the given list.
* \param num_mime_types the number of mime-types in the mime_types list.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
@@ -269,10 +269,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback
extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
/**
* Get the data from clipboard for a given mime type.
* Get the data from the clipboard for a given mime type.
*
* The size of text data does not include the terminator, but the text is
* guaranteed to be null terminated.
* guaranteed to be null-terminated.
*
* \param mime_type the mime type to read from the clipboard.
* \param size a pointer filled in with the length of the returned data.
@@ -292,8 +292,8 @@ extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, s
/**
* Query whether there is data in the clipboard for the provided mime type.
*
* \param mime_type the mime type to check for data for.
* \returns true if there exists data in clipboard for the provided mime type,
* \param mime_type the mime type to check for data.
* \returns true if data exists in the clipboard for the provided mime type,
* false if it does not.
*
* \threadsafety This function should only be called on the main thread.
@@ -310,7 +310,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
*
* \param num_mime_types a pointer filled with the number of mime types, may
* be NULL.
* \returns a null terminated array of strings with mime types, or NULL on
* \returns a null-terminated array of strings with mime types, or NULL on
* failure; call SDL_GetError() for more information. This should be
* freed with SDL_free() when it is no longer needed.
*

View File

@@ -84,8 +84,8 @@ typedef struct SDL_DialogFileFilter
* - A pointer to NULL, the user either didn't choose any file or canceled the
* dialog.
* - A pointer to non-`NULL`, the user chose one or more files. The argument
* is a null-terminated list of pointers to C strings, each containing a
* path.
* is a null-terminated array of pointers to UTF-8 encoded strings, each
* containing a path.
*
* The filelist argument should not be freed; it will automatically be freed
* when the callback returns.

View File

@@ -46,7 +46,7 @@
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
#ifdef __clang__
#if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
#ifndef __PRFCHWINTRIN_H
#define __PRFCHWINTRIN_H
static __inline__ void __attribute__((__always_inline__, __nodebug__))
@@ -128,7 +128,7 @@ _m_prefetch(void *__P)
* \sa SDL_BIG_ENDIAN
*/
#define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
#elif defined(SDL_PLATFORM_LINUX)
#elif defined(SDL_PLATFORM_LINUX) || defined(__GLIBC__)
#include <endian.h>
#define SDL_BYTEORDER __BYTE_ORDER
#elif defined(SDL_PLATFORM_SOLARIS)
@@ -486,7 +486,7 @@ SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return x_but_byteswapped; }
*
* \since This function is available since SDL 3.2.0.
*/
SDL_FORCE_INLINE Uint32 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
/**
* Swap a 16-bit value from littleendian to native byte order.

View File

@@ -132,7 +132,7 @@ typedef enum SDL_EventType
/* Window events */
/* 0x200 was SDL_WINDOWEVENT, reserve the number for sdl2-compat */
/* 0x201 was SDL_EVENT_SYSWM, reserve the number for sdl2-compat */
/* 0x201 was SDL_SYSWMEVENT, reserve the number for sdl2-compat */
SDL_EVENT_WINDOW_SHOWN = 0x202, /**< Window has been shown */
SDL_EVENT_WINDOW_HIDDEN, /**< Window has been hidden */
SDL_EVENT_WINDOW_EXPOSED, /**< Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event */
@@ -492,6 +492,8 @@ typedef struct SDL_MouseWheelEvent
SDL_MouseWheelDirection direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */
float mouse_x; /**< X coordinate, relative to window */
float mouse_y; /**< Y coordinate, relative to window */
Sint32 integer_x; /**< The amount scrolled horizontally, accumulated to whole scroll "ticks" (added in 3.2.12) */
Sint32 integer_y; /**< The amount scrolled vertically, accumulated to whole scroll "ticks" (added in 3.2.12) */
} SDL_MouseWheelEvent;
/**
@@ -1108,7 +1110,7 @@ typedef enum SDL_EventAction
* \param numevents if action is SDL_ADDEVENT, the number of events to add
* back to the event queue; if action is SDL_PEEKEVENT or
* SDL_GETEVENT, the maximum number of events to retrieve.
* \param action action to take; see [[#action|Remarks]] for details.
* \param action action to take; see [Remarks](#remarks) for details.
* \param minType minimum value of the event type to be considered;
* SDL_EVENT_FIRST is a safe choice.
* \param maxType maximum value of the event type to be considered;

View File

@@ -35,13 +35,14 @@
* can render offscreen entirely, perhaps for image processing, and not use a
* window at all.
*
* Next the app prepares static data (things that are created once and used
* Next, the app prepares static data (things that are created once and used
* over and over). For example:
*
* - Shaders (programs that run on the GPU): use SDL_CreateGPUShader().
* - Vertex buffers (arrays of geometry data) and other data rendering will
* need: use SDL_UploadToGPUBuffer().
* - Textures (images): use SDL_UploadToGPUTexture().
* - Vertex buffers (arrays of geometry data) and other rendering data: use
* SDL_CreateGPUBuffer() and SDL_UploadToGPUBuffer().
* - Textures (images): use SDL_CreateGPUTexture() and
* SDL_UploadToGPUTexture().
* - Samplers (how textures should be read from): use SDL_CreateGPUSampler().
* - Render pipelines (precalculated rendering state): use
* SDL_CreateGPUGraphicsPipeline()
@@ -223,8 +224,8 @@
* - `drawIndirectFirstInstance`
*
* **D3D12:** Supported on Windows 10 or newer, Xbox One (GDK), and Xbox
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level
* 11_1.
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level 11_0 and
* Resource Binding Tier 2 or above.
*
* **Metal:** Supported on macOS 10.14+ and iOS/tvOS 13.0+. Hardware
* requirements vary by operating system:
@@ -1090,7 +1091,7 @@ typedef enum SDL_GPUCompareOp
SDL_GPU_COMPAREOP_LESS_OR_EQUAL, /**< The comparison evaluates reference <= test. */
SDL_GPU_COMPAREOP_GREATER, /**< The comparison evaluates reference > test. */
SDL_GPU_COMPAREOP_NOT_EQUAL, /**< The comparison evaluates reference != test. */
SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evalutes reference >= test. */
SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evaluates reference >= test. */
SDL_GPU_COMPAREOP_ALWAYS /**< The comparison always evaluates true. */
} SDL_GPUCompareOp;
@@ -1495,9 +1496,16 @@ typedef struct SDL_GPUIndirectDispatchCommand
/**
* A structure specifying the parameters of a sampler.
*
* Note that mip_lod_bias is a no-op for the Metal driver. For Metal, LOD bias
* must be applied via shader instead.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreateGPUSampler
* \sa SDL_GPUFilter
* \sa SDL_GPUSamplerMipmapMode
* \sa SDL_GPUSamplerAddressMode
* \sa SDL_GPUCompareOp
*/
typedef struct SDL_GPUSamplerCreateInfo
{
@@ -1536,14 +1544,14 @@ typedef struct SDL_GPUSamplerCreateInfo
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_GPUVertexAttribute
* \sa SDL_GPUVertexInputState
* \sa SDL_GPUVertexInputRate
*/
typedef struct SDL_GPUVertexBufferDescription
{
Uint32 slot; /**< The binding slot of the vertex buffer. */
Uint32 pitch; /**< The byte pitch between consecutive elements of the vertex buffer. */
Uint32 pitch; /**< The size of a single element + the offset between elements. */
SDL_GPUVertexInputRate input_rate; /**< Whether attribute addressing is a function of the vertex index or instance index. */
Uint32 instance_step_rate; /**< The number of instances to draw using the same per-instance data before advancing in the instance buffer by one element. Ignored unless input_rate is SDL_GPU_VERTEXINPUTRATE_INSTANCE */
Uint32 instance_step_rate; /**< Reserved for future use. Must be set to 0. */
} SDL_GPUVertexBufferDescription;
/**
@@ -1713,10 +1721,13 @@ typedef struct SDL_GPUTransferBufferCreateInfo
* A structure specifying the parameters of the graphics pipeline rasterizer
* state.
*
* NOTE: Some backend APIs (D3D11/12) will enable depth clamping even if
* enable_depth_clip is true. If you rely on this clamp+clip behavior,
* consider enabling depth clip and then manually clamping depth in your
* fragment shaders on Metal and Vulkan.
* Note that SDL_GPU_FILLMODE_LINE is not supported on many Android devices.
* For those devices, the fill mode will automatically fall back to FILL.
*
* Also note that the D3D12 driver will enable depth clamping even if
* enable_depth_clip is true. If you need this clamp+clip behavior, consider
* enabling depth clip and then manually clamping depth in your fragment
* shaders on Metal and Vulkan.
*
* \since This struct is available since SDL 3.2.0.
*
@@ -1747,8 +1758,8 @@ typedef struct SDL_GPURasterizerState
typedef struct SDL_GPUMultisampleState
{
SDL_GPUSampleCount sample_count; /**< The number of samples to be used in rasterization. */
Uint32 sample_mask; /**< Determines which samples get updated in the render targets. Treated as 0xFFFFFFFF if enable_mask is false. */
bool enable_mask; /**< Enables sample masking. */
Uint32 sample_mask; /**< Reserved for future use. Must be set to 0. */
bool enable_mask; /**< Reserved for future use. Must be set to false. */
Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
@@ -1798,6 +1809,8 @@ typedef struct SDL_GPUColorTargetDescription
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_GPUGraphicsPipelineCreateInfo
* \sa SDL_GPUColorTargetDescription
* \sa SDL_GPUTextureFormat
*/
typedef struct SDL_GPUGraphicsPipelineTargetInfo
{
@@ -2454,9 +2467,9 @@ extern SDL_DECLSPEC SDL_GPUShader * SDLCALL SDL_CreateGPUShader(
* - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT`: (Direct3D 12 only)
* if the texture usage is SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET, clear
* the texture to a depth of this value. Defaults to zero.
* - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8`: (Direct3D 12
* - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER`: (Direct3D 12
* only) if the texture usage is SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET,
* clear the texture to a stencil of this value. Defaults to zero.
* clear the texture to a stencil of this Uint8 value. Defaults to zero.
* - `SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING`: a name that can be displayed
* in debugging tools.
*
@@ -2487,7 +2500,7 @@ extern SDL_DECLSPEC SDL_GPUTexture * SDLCALL SDL_CreateGPUTexture(
#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT "SDL.gpu.texture.create.d3d12.clear.b"
#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_A_FLOAT "SDL.gpu.texture.create.d3d12.clear.a"
#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT "SDL.gpu.texture.create.d3d12.clear.depth"
#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8 "SDL.gpu.texture.create.d3d12.clear.stencil"
#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER "SDL.gpu.texture.create.d3d12.clear.stencil"
#define SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING "SDL.gpu.texture.create.name"
/**
@@ -2635,7 +2648,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_InsertGPUDebugLabel(
const char *text);
/**
* Begins a debug group with an arbitary name.
* Begins a debug group with an arbitrary name.
*
* Used for denoting groups of calls when viewing the command buffer
* callstream in a graphics debugging tool.
@@ -3762,7 +3775,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ReleaseWindowFromGPUDevice(
* supported via SDL_WindowSupportsGPUPresentMode /
* SDL_WindowSupportsGPUSwapchainComposition prior to calling this function.
*
* SDL_GPU_PRESENTMODE_VSYNC and SDL_GPU_SWAPCHAINCOMPOSITION_SDR are always
* SDL_GPU_PRESENTMODE_VSYNC with SDL_GPU_SWAPCHAINCOMPOSITION_SDR are always
* supported.
*
* \param device a GPU context.
@@ -3920,6 +3933,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WaitForGPUSwapchain(
* freed by the user. You MUST NOT call this function from any thread other
* than the one that created the window.
*
* The swapchain texture is write-only and cannot be used as a sampler or for
* another reading operation.
*
* \param command_buffer a command buffer.
* \param window a window that has been claimed.
* \param swapchain_texture a pointer filled in with a swapchain texture
@@ -3938,6 +3954,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WaitForGPUSwapchain(
*
* \sa SDL_SubmitGPUCommandBuffer
* \sa SDL_SubmitGPUCommandBufferAndAcquireFence
* \sa SDL_AcquireGPUSwapchainTexture
*/
extern SDL_DECLSPEC bool SDLCALL SDL_WaitAndAcquireGPUSwapchainTexture(
SDL_GPUCommandBuffer *command_buffer,
@@ -4128,7 +4145,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GPUTextureSupportsFormat(
* \param device a GPU context.
* \param format the texture format to check.
* \param sample_count the sample count to check.
* \returns a hardware-specific version of min(preferred, possible).
* \returns whether the sample count is supported for this texture format.
*
* \since This function is available since SDL 3.2.0.
*/

View File

@@ -595,7 +595,7 @@ extern "C" {
* A variable that limits what CPU features are available.
*
* By default, SDL marks all features the current CPU supports as available.
* This hint allows to limit these to a subset.
* This hint allows the enabled features to be limited to a subset.
*
* When the hint is unset, or empty, SDL will enable all detected CPU
* features.
@@ -1074,8 +1074,8 @@ extern "C" {
*
* By default, SDL will try all available GPU backends in a reasonable order
* until it finds one that can work, but this hint allows the app or user to
* force a specific target, such as "direct3d11" if, say, your hardware
* supports D3D12 but want to try using D3D11 instead.
* force a specific target, such as "direct3d12" if, say, your hardware
* supports Vulkan but you want to try using D3D12 instead.
*
* This hint should be set before any GPU functions are called.
*
@@ -2026,8 +2026,8 @@ extern "C" {
*
* The variable can be set to the following values:
*
* - "0": RAWINPUT drivers are not used.
* - "1": RAWINPUT drivers are used. (default)
* - "0": RAWINPUT drivers are not used. (default)
* - "1": RAWINPUT drivers are used.
*
* This hint should be set before SDL is initialized.
*
@@ -2126,8 +2126,8 @@ extern "C" {
*
* The variable can be set to the following values:
*
* - "0": WGI is not used.
* - "1": WGI is used. (default)
* - "0": WGI is not used. (default)
* - "1": WGI is used.
*
* This hint should be set before SDL is initialized.
*
@@ -2191,6 +2191,28 @@ extern "C" {
*/
#define SDL_HINT_JOYSTICK_ZERO_CENTERED_DEVICES "SDL_JOYSTICK_ZERO_CENTERED_DEVICES"
/**
* A variable containing a list of devices and their desired number of haptic
* (force feedback) enabled axis.
*
* The format of the string is a comma separated list of USB VID/PID pairs in
* hexadecimal form plus the number of desired axes, e.g.
*
* `0xAAAA/0xBBBB/1,0xCCCC/0xDDDD/3`
*
* This hint supports a "wildcard" device that will set the number of haptic
* axes on all initialized haptic devices which were not defined explicitly in
* this hint.
*
* `0xFFFF/0xFFFF/1`
*
* This hint should be set before a controller is opened. The number of haptic
* axes won't exceed the number of real axes found on the device.
*
* \since This hint is available since SDL 3.2.5.
*/
#define SDL_HINT_JOYSTICK_HAPTIC_AXES "SDL_JOYSTICK_HAPTIC_AXES"
/**
* A variable that controls keycode representation in keyboard events.
*
@@ -3585,6 +3607,22 @@ extern "C" {
*/
#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER"
/**
* A variable controlling whether SDL should call XSelectInput() to enable
* input events on X11 windows wrapped by SDL windows.
*
* The variable can be set to the following values:
*
* - "0": Don't call XSelectInput(), assuming the native window code has done
* it already.
* - "1": Call XSelectInput() to enable input events. (default)
*
* This hint should be set before creating a window.
*
* \since This hint is available since SDL 3.2.10.
*/
#define SDL_HINT_VIDEO_X11_EXTERNAL_WINDOW_INPUT "SDL_VIDEO_X11_EXTERNAL_WINDOW_INPUT"
/**
* A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint
* should be used.

View File

@@ -79,7 +79,7 @@ typedef Uint32 SDL_InitFlags;
#define SDL_INIT_AUDIO 0x00000010u /**< `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS` */
#define SDL_INIT_VIDEO 0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread */
#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD */
#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS` */
#define SDL_INIT_HAPTIC 0x00001000u
#define SDL_INIT_GAMEPAD 0x00002000u /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */
#define SDL_INIT_EVENTS 0x00004000u

View File

@@ -41,8 +41,8 @@
* "system", "audio", "video", "render", "input", "test", or `*` for any
* unspecified category.
*
* The level can be a numeric level, one of "verbose", "debug", "info",
* "warn", "error", "critical", or "quiet" to disable that category.
* The level can be a numeric level, one of "trace", "verbose", "debug",
* "info", "warn", "error", "critical", or "quiet" to disable that category.
*
* You can omit the category if you want to set the logging level for all
* categories.

View File

@@ -28,6 +28,9 @@
* should look like this:
*
* ```c
* #include <SDL3/SDL.h>
* #include <SDL3/SDL_main.h>
*
* int main(int argc, char *argv[])
* {
* }
@@ -38,9 +41,9 @@
* This is also where an app can be configured to use the main callbacks, via
* the SDL_MAIN_USE_CALLBACKS macro.
*
* This is a "single-header library," which is to say that including this
* header inserts code into your program, and you should only include it once
* in most cases. SDL.h does not include this header automatically.
* SDL_main.h is a "single-header library," which is to say that including
* this header inserts code into your program, and you should only include it
* once in most cases. SDL.h does not include this header automatically.
*
* For more information, see:
*

View File

@@ -517,7 +517,7 @@ typedef enum SDL_PackedLayout
* ABGR32, define a platform-independent encoding into bytes in the order
* specified. For example, in RGB24 data, each pixel is encoded in 3 bytes
* (red, green, blue) in that order, and in ABGR32 data, each pixel is
* encoded in 4 bytes alpha, blue, green, red) in that order. Use these
* encoded in 4 bytes (alpha, blue, green, red) in that order. Use these
* names if the property of a format that is important to you is the order
* of the bytes in memory or on disk.
* - Names with a bit count per component, such as ARGB8888 and XRGB1555, are
@@ -676,6 +676,9 @@ typedef enum SDL_PixelFormat
SDL_PIXELFORMAT_EXTERNAL_OES = 0x2053454fu, /**< Android video texture format */
/* SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ') */
SDL_PIXELFORMAT_MJPG = 0x47504a4du, /**< Motion JPEG */
/* SDL_DEFINE_PIXELFOURCC('M', 'J', 'P', 'G') */
/* Aliases for RGBA byte arrays of color data, for the current platform */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888,

View File

@@ -79,6 +79,10 @@ typedef enum SDL_PowerState
* It's possible a platform can only report battery percentage or time left
* but not both.
*
* On some platforms, retrieving power supply details might be expensive. If
* you want to display continuous status you could call this function every
* minute or so.
*
* \param seconds a pointer filled in with the seconds of battery life left,
* or NULL to ignore. This will be filled in with -1 if we
* can't determine a value or there is no battery.

View File

@@ -490,6 +490,9 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetRendererProperties(SDL_Rende
* This returns the true output size in pixels, ignoring any render targets or
* logical size and presentation.
*
* For the output size of the current rendering target, with logical size
* adjustments, use SDL_GetCurrentRenderOutputSize() instead.
*
* \param renderer the rendering context.
* \param w a pointer filled in with the width in pixels.
* \param h a pointer filled in with the height in pixels.
@@ -508,9 +511,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderOutputSize(SDL_Renderer *renderer,
* Get the current output size in pixels of a rendering context.
*
* If a rendering target is active, this will return the size of the rendering
* target in pixels, otherwise if a logical size is set, it will return the
* logical size, otherwise it will return the value of
* SDL_GetRenderOutputSize().
* target in pixels, otherwise return the value of SDL_GetRenderOutputSize().
*
* Rendering target or not, the output will be adjusted by the current logical
* presentation state, dictated by SDL_SetRenderLogicalPresentation().
*
* \param renderer the rendering context.
* \param w a pointer filled in with the current width.
@@ -1318,6 +1322,11 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture *texture);
* To stop rendering to a texture and render to the window again, call this
* function with a NULL `texture`.
*
* Viewport, cliprect, scale, and logical presentation are unique to each
* render target. Get and set functions for these states apply to the current
* render target set by this function, and those states persist on each target
* when the current render target changes.
*
* \param renderer the rendering context.
* \param texture the targeted texture, which must be created with the
* `SDL_TEXTUREACCESS_TARGET` flag, or NULL to render to the
@@ -1351,25 +1360,39 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, SDL
extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer);
/**
* Set a device independent resolution and presentation mode for rendering.
* Set a device-independent resolution and presentation mode for rendering.
*
* This function sets the width and height of the logical rendering output.
* The renderer will act as if the window is always the requested dimensions,
* scaling to the actual window resolution as necessary.
* The renderer will act as if the current render target is always the
* requested dimensions, scaling to the actual resolution as necessary.
*
* This can be useful for games that expect a fixed size, but would like to
* scale the output to whatever is available, regardless of how a user resizes
* a window, or if the display is high DPI.
*
* Logical presentation can be used with both render target textures and the
* renderer's window; the state is unique to each render target, and this
* function sets the state for the current render target. It might be useful
* to draw to a texture that matches the window dimensions with logical
* presentation enabled, and then draw that texture across the entire window
* with logical presentation disabled. Be careful not to render both with
* logical presentation enabled, however, as this could produce
* double-letterboxing, etc.
*
* You can disable logical coordinates by setting the mode to
* SDL_LOGICAL_PRESENTATION_DISABLED, and in that case you get the full pixel
* resolution of the output window; it is safe to toggle logical presentation
* resolution of the render target; it is safe to toggle logical presentation
* during the rendering of a frame: perhaps most of the rendering is done to
* specific dimensions but to make fonts look sharp, the app turns off logical
* presentation while drawing text.
* presentation while drawing text, for example.
*
* Letterboxing will only happen if logical presentation is enabled during
* SDL_RenderPresent; be sure to reenable it first if you were using it.
* For the renderer's window, letterboxing is drawn into the framebuffer if
* logical presentation is enabled during SDL_RenderPresent; be sure to
* reenable it before presenting if you were toggling it, otherwise the
* letterbox areas might have artifacts from previous frames (or artifacts
* from external overlays, etc). Letterboxing is never drawn into texture
* render targets; be sure to call SDL_RenderClear() before drawing into the
* texture so the letterboxing areas are cleared, if appropriate.
*
* You can convert coordinates in an event into rendering coordinates using
* SDL_ConvertEventToRenderCoordinates().
@@ -1397,6 +1420,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderLogicalPresentation(SDL_Renderer *
* This function gets the width and height of the logical rendering output, or
* the output size in pixels if a logical resolution is not enabled.
*
* Each render target has its own logical presentation state. This function
* gets the state for the current render target.
*
* \param renderer the rendering context.
* \param w an int to be filled with the width.
* \param h an int to be filled with the height.
@@ -1420,6 +1446,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderLogicalPresentation(SDL_Renderer *
* presentation is disabled, it will fill the rectangle with the output size,
* in pixels.
*
* Each render target has its own logical presentation state. This function
* gets the rectangle for the current render target.
*
* \param renderer the rendering context.
* \param rect a pointer filled in with the final presentation rectangle, may
* be NULL.
@@ -1536,6 +1565,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ConvertEventToRenderCoordinates(SDL_Rendere
*
* The area's width and height must be >= 0.
*
* Each render target has its own viewport. This function sets the viewport
* for the current render target.
*
* \param renderer the rendering context.
* \param rect the SDL_Rect structure representing the drawing area, or NULL
* to set the viewport to the entire target.
@@ -1554,6 +1586,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderViewport(SDL_Renderer *renderer, c
/**
* Get the drawing area for the current target.
*
* Each render target has its own viewport. This function gets the viewport
* for the current render target.
*
* \param renderer the rendering context.
* \param rect an SDL_Rect structure filled in with the current drawing area.
* \returns true on success or false on failure; call SDL_GetError() for more
@@ -1572,8 +1607,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderViewport(SDL_Renderer *renderer, S
* Return whether an explicit rectangle was set as the viewport.
*
* This is useful if you're saving and restoring the viewport and want to know
* whether you should restore a specific rectangle or NULL. Note that the
* viewport is always reset when changing rendering targets.
* whether you should restore a specific rectangle or NULL.
*
* Each render target has its own viewport. This function checks the viewport
* for the current render target.
*
* \param renderer the rendering context.
* \returns true if the viewport was set to a specific rectangle, or false if
@@ -1613,6 +1650,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderSafeArea(SDL_Renderer *renderer, S
/**
* Set the clip rectangle for rendering on the specified target.
*
* Each render target has its own clip rectangle. This function sets the
* cliprect for the current render target.
*
* \param renderer the rendering context.
* \param rect an SDL_Rect structure representing the clip area, relative to
* the viewport, or NULL to disable clipping.
@@ -1631,6 +1671,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderClipRect(SDL_Renderer *renderer, c
/**
* Get the clip rectangle for the current target.
*
* Each render target has its own clip rectangle. This function gets the
* cliprect for the current render target.
*
* \param renderer the rendering context.
* \param rect an SDL_Rect structure filled in with the current clipping area
* or an empty rectangle if clipping is disabled.
@@ -1647,7 +1690,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderClipRect(SDL_Renderer *renderer, c
extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderClipRect(SDL_Renderer *renderer, SDL_Rect *rect);
/**
* Get whether clipping is enabled on the given renderer.
* Get whether clipping is enabled on the given render target.
*
* Each render target has its own clip rectangle. This function checks the
* cliprect for the current render target.
*
* \param renderer the rendering context.
* \returns true if clipping is enabled or false if not; call SDL_GetError()
@@ -1673,6 +1719,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderClipEnabled(SDL_Renderer *renderer);
* will be handled using the appropriate quality hints. For best results use
* integer scaling factors.
*
* Each render target has its own scale. This function sets the scale for the
* current render target.
*
* \param renderer the rendering context.
* \param scaleX the horizontal scaling factor.
* \param scaleY the vertical scaling factor.
@@ -1690,6 +1739,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderScale(SDL_Renderer *renderer, floa
/**
* Get the drawing scale for the current target.
*
* Each render target has its own scale. This function gets the scale for the
* current render target.
*
* \param renderer the rendering context.
* \param scaleX a pointer filled in with the horizontal scaling factor.
* \param scaleY a pointer filled in with the vertical scaling factor.
@@ -2247,15 +2299,21 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer,
/**
* Read pixels from the current rendering target.
*
* The returned surface should be freed with SDL_DestroySurface()
* The returned surface contains pixels inside the desired area clipped to the
* current viewport, and should be freed with SDL_DestroySurface().
*
* Note that this returns the actual pixels on the screen, so if you are using
* logical presentation you should use SDL_GetRenderLogicalPresentationRect()
* to get the area containing your content.
*
* **WARNING**: This is a very slow operation, and should not be used
* frequently. If you're using this on the main rendering target, it should be
* called after rendering and before SDL_RenderPresent().
*
* \param renderer the rendering context.
* \param rect an SDL_Rect structure representing the area in pixels relative
* to the to current viewport, or NULL for the entire viewport.
* \param rect an SDL_Rect structure representing the area to read, which will
* be clipped to the current viewport, or NULL for the entire
* viewport.
* \returns a new SDL_Surface on success or NULL on failure; call
* SDL_GetError() for more information.
*
@@ -2554,7 +2612,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, flo
* Draw debug text to an SDL_Renderer.
*
* This function will render a printf()-style format string to a renderer.
* Note that this is a convinence function for debugging, with severe
* Note that this is a convenience function for debugging, with severe
* limitations, and is not intended to be used for production apps and games.
*
* For the full list of limitations and other useful information, see

View File

@@ -208,7 +208,7 @@ typedef enum SDL_Scancode
SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO
* keyboards have over ANSI ones,
* located between left shift and Y.
* located between left shift and Z.
* Produces GRAVE ACCENT and TILDE in a
* US or UK Mac layout, REVERSE SOLIDUS
* (backslash) and VERTICAL LINE in a

View File

@@ -138,7 +138,8 @@ typedef enum SDL_SensorType
SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */
SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */
SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */
SDL_SENSOR_GYRO_R /**< Gyroscope for right Joy-Con controller */
SDL_SENSOR_GYRO_R, /**< Gyroscope for right Joy-Con controller */
SDL_SENSOR_COUNT
} SDL_SensorType;

View File

@@ -1299,8 +1299,11 @@ extern "C" {
*
* If `size` is 0, it will be set to 1.
*
* If you want to allocate memory aligned to a specific alignment, consider
* using SDL_aligned_alloc().
* If the allocation is successful, the returned pointer is guaranteed to be
* aligned to either the *fundamental alignment* (`alignof(max_align_t)` in
* C11 and later) or `2 * sizeof(void *)`, whichever is smaller. Use
* SDL_aligned_alloc() if you need to allocate memory aligned to an alignment
* greater than this guarantee.
*
* \param size the size to allocate.
* \returns a pointer to the allocated memory, or NULL if allocation failed.
@@ -1323,6 +1326,10 @@ extern SDL_DECLSPEC SDL_MALLOC void * SDLCALL SDL_malloc(size_t size);
*
* If either of `nmemb` or `size` is 0, they will both be set to 1.
*
* If the allocation is successful, the returned pointer is guaranteed to be
* aligned to either the *fundamental alignment* (`alignof(max_align_t)` in
* C11 and later) or `2 * sizeof(void *)`, whichever is smaller.
*
* \param nmemb the number of elements in the array.
* \param size the size of each element of the array.
* \returns a pointer to the allocated array, or NULL if allocation failed.
@@ -1357,6 +1364,11 @@ extern SDL_DECLSPEC SDL_MALLOC SDL_ALLOC_SIZE2(1, 2) void * SDLCALL SDL_calloc(s
* - If it returns NULL (indicating failure), then `mem` will remain valid and
* must still be freed with SDL_free().
*
* If the allocation is successfully resized, the returned pointer is
* guaranteed to be aligned to either the *fundamental alignment*
* (`alignof(max_align_t)` in C11 and later) or `2 * sizeof(void *)`,
* whichever is smaller.
*
* \param mem a pointer to allocated memory to reallocate, or NULL.
* \param size the new size of the memory.
* \returns a pointer to the newly allocated memory, or NULL if allocation
@@ -3414,7 +3426,7 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes
* Convert an integer into a string.
*
* This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36.
*
* Note that this function will overflow a buffer if `str` is not large enough
@@ -3442,7 +3454,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_itoa(int value, char *str, int radix);
* Convert an unsigned integer into a string.
*
* This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36.
*
* Note that this function will overflow a buffer if `str` is not large enough
@@ -3470,7 +3482,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_uitoa(unsigned int value, char *str, int
* Convert a long integer into a string.
*
* This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36.
*
* Note that this function will overflow a buffer if `str` is not large enough
@@ -3498,7 +3510,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ltoa(long value, char *str, int radix);
* Convert an unsigned long integer into a string.
*
* This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36.
*
* Note that this function will overflow a buffer if `str` is not large enough
@@ -3528,7 +3540,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ultoa(unsigned long value, char *str, int
* Convert a long long integer into a string.
*
* This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36.
*
* Note that this function will overflow a buffer if `str` is not large enough
@@ -3556,7 +3568,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_lltoa(long long value, char *str, int rad
* Convert an unsigned long long integer into a string.
*
* This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36.
*
* Note that this function will overflow a buffer if `str` is not large enough
@@ -3911,7 +3923,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str
extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen);
/**
* Searches a string for the first occurence of any character contained in a
* Searches a string for the first occurrence of any character contained in a
* breakset, and returns a pointer from the string to that character.
*
* \param str The null-terminated string to be searched. Must not be NULL, and
@@ -3919,7 +3931,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *st
* \param breakset A null-terminated string containing the list of characters
* to look for. Must not be NULL, and must not overlap with
* `str`.
* \returns A pointer to the location, in str, of the first occurence of a
* \returns A pointer to the location, in str, of the first occurrence of a
* character present in the breakset, or NULL if none is found.
*
* \threadsafety It is safe to call this function from any thread.
@@ -4243,14 +4255,14 @@ extern SDL_DECLSPEC int SDLCALL SDL_vasprintf(char **strp, SDL_PRINTF_FORMAT_STR
/**
* Seeds the pseudo-random number generator.
*
* Reusing the seed number will cause SDL_rand_*() to repeat the same stream
* of 'random' numbers.
* Reusing the seed number will cause SDL_rand() to repeat the same stream of
* 'random' numbers.
*
* \param seed the value to use as a random number seed, or 0 to use
* SDL_GetPerformanceCounter().
*
* \threadsafety This should be called on the same thread that calls
* SDL_rand*()
* SDL_rand()
*
* \since This function is available since SDL 3.2.0.
*
@@ -4644,7 +4656,7 @@ extern SDL_DECLSPEC float SDLCALL SDL_atanf(float x);
*
* Domain: `-INF <= x <= INF`, `-INF <= y <= INF`
*
* Range: `-Pi/2 <= y <= Pi/2`
* Range: `-Pi <= y <= Pi`
*
* This function operates on double-precision floating point values, use
* SDL_atan2f for single-precision floats.
@@ -4680,7 +4692,7 @@ extern SDL_DECLSPEC double SDLCALL SDL_atan2(double y, double x);
*
* Domain: `-INF <= x <= INF`, `-INF <= y <= INF`
*
* Range: `-Pi/2 <= y <= Pi/2`
* Range: `-Pi <= y <= Pi`
*
* This function operates on single-precision floating point values, use
* SDL_atan2 for double-precision floats.
@@ -5809,7 +5821,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd);
* This function converts text between encodings, reading from and writing to
* a buffer.
*
* It returns the number of succesful conversions on success. On error,
* It returns the number of successful conversions on success. On error,
* SDL_ICONV_E2BIG is returned when the output buffer is too small, or
* SDL_ICONV_EILSEQ is returned when an invalid input sequence is encountered,
* or SDL_ICONV_EINVAL is returned when an incomplete input sequence is
@@ -5962,14 +5974,17 @@ size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size);
size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size);
#endif
#ifndef _WIN32
/* strdup is not ANSI but POSIX, and its prototype might be hidden... */
/* not for windows: might conflict with string.h where strdup may have
* dllimport attribute: https://github.com/libsdl-org/SDL/issues/12948 */
char *strdup(const char *str);
#endif
/* Starting LLVM 16, the analyser errors out if these functions do not have
their prototype defined (clang-diagnostic-implicit-function-declaration) */
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#define SDL_malloc malloc
#define SDL_calloc calloc

View File

@@ -450,7 +450,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CloseStorage(SDL_Storage *storage);
*
* This function should be called in regular intervals until it returns true -
* however, it is not recommended to spinwait on this call, as the backend may
* depend on a synchronous message loop.
* depend on a synchronous message loop. You might instead poll this in your
* game's main loop while processing events and drawing a loading screen.
*
* \param storage a storage container to query.
* \returns true if the container is ready, false otherwise.

View File

@@ -82,6 +82,7 @@ typedef Uint32 SDL_SurfaceFlags;
*/
typedef enum SDL_ScaleMode
{
SDL_SCALEMODE_INVALID = -1,
SDL_SCALEMODE_NEAREST, /**< nearest pixel sampling */
SDL_SCALEMODE_LINEAR /**< linear filtering */
} SDL_ScaleMode;
@@ -120,6 +121,9 @@ typedef enum SDL_FlipMode
* format with a pitch of 32 would consist of 32x32 bytes of Y plane followed
* by 32x16 bytes of UV plane.
*
* When a surface holds MJPG format data, pixels points at the compressed JPEG
* image and pitch is the length of that data.
*
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_CreateSurface
@@ -153,6 +157,8 @@ typedef struct SDL_Surface SDL_Surface;
* \returns the new SDL_Surface structure that is created or NULL on failure;
* call SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreateSurfaceFrom
@@ -181,6 +187,8 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_CreateSurface(int width, int heigh
* \returns the new SDL_Surface structure that is created or NULL on failure;
* call SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreateSurface
@@ -195,6 +203,8 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_CreateSurfaceFrom(int width, int h
*
* \param surface the SDL_Surface to free.
*
* \threadsafety No other thread should be using the surface when it is freed.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreateSurface
@@ -221,11 +231,17 @@ extern SDL_DECLSPEC void SDLCALL SDL_DestroySurface(SDL_Surface *surface);
* the same tone mapping that Chrome uses for HDR content, the form "*=N",
* where N is a floating point scale factor applied in linear space, and
* "none", which disables tone mapping. This defaults to "chrome".
* - `SDL_PROP_SURFACE_HOTSPOT_X_NUMBER`: the hotspot pixel offset from the
* left edge of the image, if this surface is being used as a cursor.
* - `SDL_PROP_SURFACE_HOTSPOT_Y_NUMBER`: the hotspot pixel offset from the
* top edge of the image, if this surface is being used as a cursor.
*
* \param surface the SDL_Surface structure to query.
* \returns a valid property ID on success or 0 on failure; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetSurfaceProperties(SDL_Surface *surface);
@@ -233,6 +249,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetSurfaceProperties(SDL_Surfac
#define SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT "SDL.surface.SDR_white_point"
#define SDL_PROP_SURFACE_HDR_HEADROOM_FLOAT "SDL.surface.HDR_headroom"
#define SDL_PROP_SURFACE_TONEMAP_OPERATOR_STRING "SDL.surface.tonemap"
#define SDL_PROP_SURFACE_HOTSPOT_X_NUMBER "SDL.surface.hotspot.x"
#define SDL_PROP_SURFACE_HOTSPOT_Y_NUMBER "SDL.surface.hotspot.y"
/**
* Set the colorspace used by a surface.
@@ -246,6 +264,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetSurfaceProperties(SDL_Surfac
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceColorspace
@@ -263,6 +283,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfaceColorspace(SDL_Surface *surface,
* \returns the colorspace used by the surface, or SDL_COLORSPACE_UNKNOWN if
* the surface is NULL.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetSurfaceColorspace
@@ -291,6 +313,8 @@ extern SDL_DECLSPEC SDL_Colorspace SDLCALL SDL_GetSurfaceColorspace(SDL_Surface
* the surface didn't have an index format); call SDL_GetError() for
* more information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetPaletteColors
@@ -307,6 +331,8 @@ extern SDL_DECLSPEC SDL_Palette * SDLCALL SDL_CreateSurfacePalette(SDL_Surface *
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreatePalette
@@ -321,6 +347,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfacePalette(SDL_Surface *surface, SDL
* \returns a pointer to the palette used by the surface, or NULL if there is
* no palette used.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetSurfacePalette
@@ -344,6 +372,8 @@ extern SDL_DECLSPEC SDL_Palette * SDLCALL SDL_GetSurfacePalette(SDL_Surface *sur
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_RemoveSurfaceAlternateImages
@@ -358,6 +388,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_AddSurfaceAlternateImage(SDL_Surface *surfa
* \param surface the SDL_Surface structure to query.
* \returns true if alternate versions are available or false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_AddSurfaceAlternateImage
@@ -383,6 +415,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SurfaceHasAlternateImages(SDL_Surface *surf
* failure; call SDL_GetError() for more information. This should be
* freed with SDL_free() when it is no longer needed.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_AddSurfaceAlternateImage
@@ -399,6 +433,8 @@ extern SDL_DECLSPEC SDL_Surface ** SDLCALL SDL_GetSurfaceImages(SDL_Surface *sur
*
* \param surface the SDL_Surface structure to update.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_AddSurfaceAlternateImage
@@ -423,6 +459,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_RemoveSurfaceAlternateImages(SDL_Surface *s
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe. The locking referred to by
* this function is making the pixels available for direct
* access, not thread-safe locking.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_MUSTLOCK
@@ -435,6 +475,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_LockSurface(SDL_Surface *surface);
*
* \param surface the SDL_Surface structure to be unlocked.
*
* \threadsafety This function is not thread safe. The locking referred to by
* this function is making the pixels available for direct
* access, not thread-safe locking.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_LockSurface
@@ -453,6 +497,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface);
* \returns a pointer to a new SDL_Surface structure or NULL on failure; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_DestroySurface
@@ -471,6 +517,8 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_LoadBMP_IO(SDL_IOStream *src, bool
* \returns a pointer to a new SDL_Surface structure or NULL on failure; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_DestroySurface
@@ -495,6 +543,8 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_LoadBMP(const char *file);
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_LoadBMP_IO
@@ -516,6 +566,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStre
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_LoadBMP
@@ -534,6 +586,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SaveBMP(SDL_Surface *surface, const char *f
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_BlitSurface
@@ -550,6 +604,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfaceRLE(SDL_Surface *surface, bool en
* \param surface the SDL_Surface structure to query.
* \returns true if the surface is RLE enabled, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetSurfaceRLE
@@ -572,6 +628,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SurfaceHasRLE(SDL_Surface *surface);
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceColorKey
@@ -588,6 +646,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfaceColorKey(SDL_Surface *surface, bo
* \param surface the SDL_Surface structure to query.
* \returns true if the surface has a color key, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetSurfaceColorKey
@@ -608,6 +668,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SurfaceHasColorKey(SDL_Surface *surface);
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetSurfaceColorKey
@@ -631,6 +693,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetSurfaceColorKey(SDL_Surface *surface, Ui
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceColorMod
@@ -649,6 +713,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfaceColorMod(SDL_Surface *surface, Ui
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceAlphaMod
@@ -669,6 +735,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetSurfaceColorMod(SDL_Surface *surface, Ui
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceAlphaMod
@@ -684,6 +752,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Ui
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceColorMod
@@ -703,6 +773,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Ui
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceBlendMode
@@ -717,6 +789,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface *surface, S
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetSurfaceBlendMode
@@ -738,6 +812,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface *surface, S
* \returns true if the rectangle intersects the surface, otherwise false and
* blits will be completely clipped.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetSurfaceClipRect
@@ -757,6 +833,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetSurfaceClipRect(SDL_Surface *surface, co
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_SetSurfaceClipRect
@@ -771,6 +849,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetSurfaceClipRect(SDL_Surface *surface, SD
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_FlipSurface(SDL_Surface *surface, SDL_FlipMode flip);
@@ -787,6 +867,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_FlipSurface(SDL_Surface *surface, SDL_FlipM
* \returns a copy of the surface or NULL on failure; call SDL_GetError() for
* more information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_DestroySurface
@@ -806,6 +888,8 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_DuplicateSurface(SDL_Surface *surf
* \returns a copy of the surface or NULL on failure; call SDL_GetError() for
* more information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_DestroySurface
@@ -831,6 +915,8 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_ScaleSurface(SDL_Surface *surface,
* \returns the new SDL_Surface structure that is created or NULL on failure;
* call SDL_GetError() for more information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_ConvertSurfaceAndColorspace
@@ -857,6 +943,8 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_ConvertSurface(SDL_Surface *surfac
* \returns the new SDL_Surface structure that is created or NULL on failure;
* call SDL_GetError() for more information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_ConvertSurface
@@ -878,6 +966,10 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_ConvertSurfaceAndColorspace(SDL_Su
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination pixels should not be used from two
* threads at once. It is safe to use the same source pixels
* from multiple threads.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_ConvertPixelsAndColorspace
@@ -907,6 +999,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ConvertPixels(int width, int height, SDL_Pi
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination pixels should not be used from two
* threads at once. It is safe to use the same source pixels
* from multiple threads.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_ConvertPixels
@@ -931,6 +1027,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ConvertPixelsAndColorspace(int width, int h
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination pixels should not be used from two
* threads at once. It is safe to use the same source pixels
* from multiple threads.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_PremultiplyAlpha(int width, int height, SDL_PixelFormat src_format, const void *src, int src_pitch, SDL_PixelFormat dst_format, void *dst, int dst_pitch, bool linear);
@@ -946,6 +1046,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_PremultiplyAlpha(int width, int height, SDL
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_PremultiplySurfaceAlpha(SDL_Surface *surface, bool linear);
@@ -966,6 +1068,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_PremultiplySurfaceAlpha(SDL_Surface *surfac
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_ClearSurface(SDL_Surface *surface, float r, float g, float b, float a);
@@ -989,6 +1093,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ClearSurface(SDL_Surface *surface, float r,
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_FillSurfaceRects
@@ -1014,6 +1120,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_FillSurfaceRect(SDL_Surface *dst, const SDL
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_FillSurfaceRect
@@ -1027,9 +1135,6 @@ extern SDL_DECLSPEC bool SDLCALL SDL_FillSurfaceRects(SDL_Surface *dst, const SD
* If either `srcrect` or `dstrect` are NULL, the entire surface (`src` or
* `dst`) is copied while ensuring clipping to `dst->clip_rect`.
*
* The final blit rectangles are saved in `srcrect` and `dstrect` after all
* clipping is performed.
*
* The blit function should not be called on a locked surface.
*
* The blit semantics for surfaces with and without blending and colorkey are
@@ -1087,9 +1192,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_FillSurfaceRects(SDL_Surface *dst, const SD
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1112,9 +1216,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurface(SDL_Surface *src, const SDL_Rec
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1137,9 +1240,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceUnchecked(SDL_Surface *src, cons
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1163,9 +1265,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceScaled(SDL_Surface *src, const S
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1178,17 +1279,17 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src
*
* \param src the SDL_Surface structure to be copied from.
* \param srcrect the SDL_Rect structure representing the rectangle to be
* copied, may not be NULL.
* copied, or NULL to copy the entire surface.
* \param dst the SDL_Surface structure that is the blit target.
* \param dstrect the SDL_Rect structure representing the target rectangle in
* the destination surface, may not be NULL.
* the destination surface, or NULL to fill the entire
* destination surface.
* \param scaleMode the SDL_ScaleMode to be used.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.4.0.
*
@@ -1212,9 +1313,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_StretchSurface(SDL_Surface *src, const SDL_
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1242,9 +1342,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceTiled(SDL_Surface *src, const SD
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1279,9 +1378,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceTiledWithScale(SDL_Surface *src,
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety The same destination surface should not be used from two
* threads at once. It is safe to use the same source surface
* from multiple threads.
* \threadsafety Only one thread should be using the `src` and `dst` surfaces
* at any given time.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1313,6 +1411,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurface9Grid(SDL_Surface *src, const SD
* \param b the blue component of the pixel in the range 0-255.
* \returns a pixel value.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_MapSurfaceRGBA
@@ -1344,6 +1444,8 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_MapSurfaceRGB(SDL_Surface *surface, Uint8
* \param a the alpha component of the pixel in the range 0-255.
* \returns a pixel value.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_MapSurfaceRGB
@@ -1373,6 +1475,8 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_MapSurfaceRGBA(SDL_Surface *surface, Uint
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_ReadSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);
@@ -1397,6 +1501,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadSurfacePixel(SDL_Surface *surface, int
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_ReadSurfacePixelFloat(SDL_Surface *surface, int x, int y, float *r, float *g, float *b, float *a);
@@ -1420,6 +1526,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadSurfacePixelFloat(SDL_Surface *surface,
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_WriteSurfacePixel(SDL_Surface *surface, int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
@@ -1440,6 +1548,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteSurfacePixel(SDL_Surface *surface, int
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_WriteSurfacePixelFloat(SDL_Surface *surface, int x, int y, float r, float g, float b, float a);

View File

@@ -62,7 +62,7 @@ extern "C" {
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_MICRO_VERSION 4
#define SDL_MICRO_VERSION 24
/**
* This macro turns the version numbers into a numeric value.

View File

@@ -426,10 +426,10 @@ typedef SDL_EGLint *(SDLCALL *SDL_EGLIntArrayCallback)(void *userdata, SDL_EGLDi
*/
typedef enum SDL_GLAttr
{
SDL_GL_RED_SIZE, /**< the minimum number of bits for the red channel of the color buffer; defaults to 3. */
SDL_GL_GREEN_SIZE, /**< the minimum number of bits for the green channel of the color buffer; defaults to 3. */
SDL_GL_BLUE_SIZE, /**< the minimum number of bits for the blue channel of the color buffer; defaults to 2. */
SDL_GL_ALPHA_SIZE, /**< the minimum number of bits for the alpha channel of the color buffer; defaults to 0. */
SDL_GL_RED_SIZE, /**< the minimum number of bits for the red channel of the color buffer; defaults to 8. */
SDL_GL_GREEN_SIZE, /**< the minimum number of bits for the green channel of the color buffer; defaults to 8. */
SDL_GL_BLUE_SIZE, /**< the minimum number of bits for the blue channel of the color buffer; defaults to 8. */
SDL_GL_ALPHA_SIZE, /**< the minimum number of bits for the alpha channel of the color buffer; defaults to 8. */
SDL_GL_BUFFER_SIZE, /**< the minimum number of bits for frame buffer size; defaults to 0. */
SDL_GL_DOUBLEBUFFER, /**< whether the output is single or double buffered; defaults to double buffering on. */
SDL_GL_DEPTH_SIZE, /**< the minimum number of bits in the depth buffer; defaults to 16. */
@@ -1041,6 +1041,10 @@ extern SDL_DECLSPEC SDL_Window ** SDLCALL SDL_GetWindows(int *count);
/**
* Create a window with the specified dimensions and flags.
*
* The window size is a request and may be different than expected based on
* the desktop layout and window manager policies. Your application should be
* prepared to handle a window of any size.
*
* `flags` may be any of the following OR'd together:
*
* - `SDL_WINDOW_FULLSCREEN`: fullscreen window at desktop resolution
@@ -1127,6 +1131,10 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, int
/**
* Create a child popup window of the specified parent window.
*
* The window size is a request and may be different than expected based on
* the desktop layout and window manager policies. Your application should be
* prepared to handle a window of any size.
*
* The flags parameter **must** contain at least one of the following:
*
* - `SDL_WINDOW_TOOLTIP`: The popup window is a tooltip and will not pass any
@@ -1159,6 +1167,15 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, int
* Popup windows implicitly do not have a border/decorations and do not appear
* on the taskbar/dock or in lists of windows such as alt-tab menus.
*
* By default, popup window positions will automatically be constrained to keep
* the entire window within display bounds. This can be overridden with the
* `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN` property.
*
* By default, popup menus will automatically grab keyboard focus from the parent
* when shown. This behavior can be overridden by setting the `SDL_WINDOW_NOT_FOCUSABLE`
* flag, setting the `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN` property to false, or
* toggling it after creation via the `SDL_SetWindowFocusable()` function.
*
* If a parent window is hidden or destroyed, any child popup windows will be
* recursively hidden or destroyed as well. Child popup windows not explicitly
* hidden will be restored when the parent is shown.
@@ -1189,12 +1206,19 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren
/**
* Create a window with the specified properties.
*
* The window size is a request and may be different than expected based on
* the desktop layout and window manager policies. Your application should be
* prepared to handle a window of any size.
*
* These are the supported properties:
*
* - `SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN`: true if the window should
* be always on top
* - `SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN`: true if the window has no
* window decoration
* - `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN`: true if the "tooltip" and
* "menu" window types should be automatically constrained to be entirely within
* display bounds (default), false if no constraints on the position are desired.
* - `SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN`: true if the
* window will be used with an externally managed graphics context.
* - `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN`: true if the window should
@@ -1309,6 +1333,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop
#define SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN "SDL.window.create.always_on_top"
#define SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN "SDL.window.create.borderless"
#define SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN "SDL.window.create.constrain_popup"
#define SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN "SDL.window.create.focusable"
#define SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN "SDL.window.create.external_graphics_context"
#define SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER "SDL.window.create.flags"
@@ -1448,7 +1473,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window)
* - `SDL_PROP_WINDOW_COCOA_WINDOW_POINTER`: the `(__unsafe_unretained)`
* NSWindow associated with the window
* - `SDL_PROP_WINDOW_COCOA_METAL_VIEW_TAG_NUMBER`: the NSInteger tag
* assocated with metal views on the window
* associated with metal views on the window
*
* On OpenVR:
*

View File

@@ -51,14 +51,14 @@
extern "C" {
#endif
/* Avoid including vulkan.h, don't define VkInstance if it's already included */
#ifdef VULKAN_H_
/* Avoid including vulkan_core.h, don't define VkInstance if it's already included */
#ifdef VULKAN_CORE_H_
#define NO_SDL_VULKAN_TYPEDEFS
#endif
#ifndef NO_SDL_VULKAN_TYPEDEFS
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) || (defined(__riscv) && __riscv_xlen == 64)
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
#else
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;

View File

@@ -174,6 +174,7 @@
#cmakedefine HAVE_MEMFD_CREATE 1
#cmakedefine HAVE_POSIX_FALLOCATE 1
#cmakedefine HAVE_SIGACTION 1
#cmakedefine HAVE_SIGTIMEDWAIT 1
#cmakedefine HAVE_SA_SIGACTION 1
#cmakedefine HAVE_ST_MTIM 1
#cmakedefine HAVE_SETJMP 1

View File

@@ -111,6 +111,9 @@ typedef unsigned int uintptr_t;
# define SDL_DISABLE_AVX 1
#endif
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
/* This can be disabled to avoid C runtime dependencies and manifest requirements */
#ifndef HAVE_LIBC
#define HAVE_LIBC 1
@@ -122,8 +125,6 @@ typedef unsigned int uintptr_t;
#define HAVE_LIMITS_H 1
#define HAVE_MATH_H 1
#define HAVE_SIGNAL_H 1
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#define HAVE_STDIO_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
@@ -153,7 +154,6 @@ typedef unsigned int uintptr_t;
#define HAVE_STRCMP 1
#define HAVE_STRNCMP 1
#define HAVE_STRPBRK 1
#define HAVE_VSSCANF 1
#define HAVE_VSNPRINTF 1
#define HAVE_ACOS 1
#define HAVE_ASIN 1
@@ -212,9 +212,6 @@ typedef unsigned int uintptr_t;
#define HAVE__FSEEKI64 1
#endif
#endif /* _MSC_VER */
#else
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#endif
/* Enable various audio drivers */

View File

@@ -65,7 +65,7 @@
// Initialization/Cleanup routines
#include "timer/SDL_timer_c.h"
#ifdef SDL_VIDEO_DRIVER_WINDOWS
#ifdef SDL_PLATFORM_WINDOWS
extern bool SDL_HelperWindowCreate(void);
extern void SDL_HelperWindowDestroy(void);
#endif
@@ -317,7 +317,7 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_DBus_Init();
#endif
#ifdef SDL_VIDEO_DRIVER_WINDOWS
#ifdef SDL_PLATFORM_WINDOWS
if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) {
if (!SDL_HelperWindowCreate()) {
goto quit_and_error;
@@ -356,7 +356,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);
if (!SDL_VideoInit(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_VIDEO);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
@@ -381,7 +383,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_AUDIO);
if (!SDL_InitAudio(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_AUDIO);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
@@ -406,7 +410,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_JOYSTICK);
if (!SDL_InitJoysticks()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_JOYSTICK);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
@@ -430,7 +436,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_GAMEPAD);
if (!SDL_InitGamepads()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_GAMEPAD);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
SDL_PopError();
goto quit_and_error;
}
} else {
@@ -493,7 +501,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
if (!SDL_CameraInit(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
@@ -511,7 +521,11 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
return SDL_ClearError();
quit_and_error:
{
SDL_PushError();
SDL_QuitSubSystem(flags_initialized);
SDL_PopError();
}
return false;
}
@@ -639,7 +653,7 @@ void SDL_Quit(void)
SDL_bInMainQuit = true;
// Quit all subsystems
#ifdef SDL_VIDEO_DRIVER_WINDOWS
#ifdef SDL_PLATFORM_WINDOWS
SDL_HelperWindowDestroy();
#endif
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);

View File

@@ -35,14 +35,6 @@
#ifdef SDL_PLATFORM_EMSCRIPTEN
#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.
@@ -252,7 +244,7 @@ static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, v
for (;;) {
bool okay = true;
/* *INDENT-OFF* */ // clang-format off
char *buf = (char *) MAIN_THREAD_EM_ASM_PTR({
int reply = MAIN_THREAD_EM_ASM_INT({
var str =
UTF8ToString($0) + '\n\n' +
'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :';
@@ -260,26 +252,32 @@ static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, v
if (reply === null) {
reply = "i";
}
return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL);
return reply.length === 1 ? reply.charCodeAt(0) : -1;
}, message);
/* *INDENT-ON* */ // clang-format on
if (SDL_strcmp(buf, "a") == 0) {
switch (reply) {
case 'a':
state = SDL_ASSERTION_ABORT;
break;
#if 0 // (currently) no break functionality on Emscripten
} else if (SDL_strcmp(buf, "b") == 0) {
case 'b':
state = SDL_ASSERTION_BREAK;
break;
#endif
} else if (SDL_strcmp(buf, "r") == 0) {
case 'r':
state = SDL_ASSERTION_RETRY;
} else if (SDL_strcmp(buf, "i") == 0) {
break;
case 'i':
state = SDL_ASSERTION_IGNORE;
} else if (SDL_strcmp(buf, "A") == 0) {
break;
case 'A':
state = SDL_ASSERTION_ALWAYS_IGNORE;
} else {
break;
default:
okay = false;
break;
}
free(buf); // This should NOT be SDL_free()
if (okay) {
break;

View File

@@ -46,4 +46,16 @@ typedef struct SDL_error
// Defined in SDL_thread.c
extern SDL_error *SDL_GetErrBuf(bool create);
// Macros to save and restore error values
#define SDL_PushError() \
char *saved_error = SDL_strdup(SDL_GetError())
#define SDL_PopError() \
do { \
if (saved_error) { \
SDL_SetError("%s", saved_error); \
SDL_free(saved_error); \
} \
} while (0)
#endif // SDL_error_c_h_

View File

@@ -19,34 +19,6 @@
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_hashtable.h"
// XXX: We can't use SDL_assert here because it's going to call into hashtable code
#ifdef NDEBUG
#define HT_ASSERT(x) (void)(0)
#else
#if (defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
#include <windows.h>
#endif
/* This is not declared in any header, although it is shared between some
parts of SDL, because we don't want anything calling it without an
extremely good reason. */
extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
static void HT_ASSERT_FAIL(const char *msg)
{
const char *caption = "SDL_HashTable Assertion Failure!";
(void)caption;
#if (defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
MessageBoxA(NULL, msg, caption, MB_OK | MB_ICONERROR);
#elif defined(HAVE_STDIO_H)
fprintf(stderr, "\n\n%s\n%s\n\n", caption, msg);
fflush(stderr);
#endif
SDL_TriggerBreakpoint();
SDL_ExitProcess(-1);
}
#define HT_ASSERT(x) if (!(x)) HT_ASSERT_FAIL("SDL_HashTable Assertion Failure: " #x)
#endif
typedef struct SDL_HashItem
{
@@ -67,47 +39,49 @@ SDL_COMPILE_TIME_ASSERT(sizeof_SDL_HashItem, sizeof(SDL_HashItem) <= MAX_HASHITE
struct SDL_HashTable
{
SDL_RWLock *lock;
SDL_RWLock *lock; // NULL if not created threadsafe
SDL_HashItem *table;
SDL_HashTable_HashFn hash;
SDL_HashTable_KeyMatchFn keymatch;
SDL_HashTable_NukeFn nuke;
void *data;
SDL_HashCallback hash;
SDL_HashKeyMatchCallback keymatch;
SDL_HashDestroyCallback destroy;
void *userdata;
Uint32 hash_mask;
Uint32 max_probe_len;
Uint32 num_occupied_slots;
bool stackable;
};
SDL_HashTable *SDL_CreateHashTable(void *data,
Uint32 num_buckets,
SDL_HashTable_HashFn hashfn,
SDL_HashTable_KeyMatchFn keymatchfn,
SDL_HashTable_NukeFn nukefn,
bool threadsafe,
bool stackable)
static Uint32 CalculateHashBucketsFromEstimate(int estimated_capacity)
{
SDL_HashTable *table;
// num_buckets must be a power of two so we can derive the bucket index with just a bit-and.
if ((num_buckets < 1) || !SDL_HasExactlyOneBitSet32(num_buckets)) {
SDL_SetError("num_buckets must be a power of two");
return NULL;
if (estimated_capacity <= 0) {
return 4; // start small, grow as necessary.
}
if (num_buckets > MAX_HASHTABLE_SIZE) {
SDL_SetError("num_buckets is too large");
return NULL;
const Uint32 estimated32 = (Uint32) estimated_capacity;
Uint32 buckets = ((Uint32) 1) << SDL_MostSignificantBitIndex32(estimated32);
if (!SDL_HasExactlyOneBitSet32(estimated32)) {
buckets <<= 1; // need next power of two up to fit overflow capacity bits.
}
table = (SDL_HashTable *)SDL_calloc(1, sizeof(SDL_HashTable));
return SDL_min(buckets, MAX_HASHTABLE_SIZE);
}
SDL_HashTable *SDL_CreateHashTable(int estimated_capacity, bool threadsafe, SDL_HashCallback hash,
SDL_HashKeyMatchCallback keymatch,
SDL_HashDestroyCallback destroy, void *userdata)
{
const Uint32 num_buckets = CalculateHashBucketsFromEstimate(estimated_capacity);
SDL_HashTable *table = (SDL_HashTable *)SDL_calloc(1, sizeof(SDL_HashTable));
if (!table) {
return NULL;
}
if (threadsafe) {
// Don't fail if we can't create a lock (single threaded environment?)
table->lock = SDL_CreateRWLock();
if (!table->lock) {
SDL_DestroyHashTable(table);
return NULL;
}
}
table->table = (SDL_HashItem *)SDL_calloc(num_buckets, sizeof(SDL_HashItem));
@@ -117,24 +91,22 @@ SDL_HashTable *SDL_CreateHashTable(void *data,
}
table->hash_mask = num_buckets - 1;
table->stackable = stackable;
table->data = data;
table->hash = hashfn;
table->keymatch = keymatchfn;
table->nuke = nukefn;
table->userdata = userdata;
table->hash = hash;
table->keymatch = keymatch;
table->destroy = destroy;
return table;
}
static SDL_INLINE Uint32 calc_hash(const SDL_HashTable *table, const void *key)
{
const Uint32 BitMixer = 0x9E3779B1u;
return table->hash(key, table->data) * BitMixer;
return table->hash(table->userdata, key) * BitMixer;
}
static SDL_INLINE Uint32 get_probe_length(Uint32 zero_idx, Uint32 actual_idx, Uint32 num_buckets)
{
// returns the probe sequence length from zero_idx to actual_idx
if (actual_idx < zero_idx) {
return num_buckets - zero_idx + actual_idx;
}
@@ -149,7 +121,7 @@ static SDL_HashItem *find_item(const SDL_HashTable *ht, const void *key, Uint32
SDL_HashItem *table = ht->table;
for (;;) {
while (true) {
SDL_HashItem *item = table + *i;
Uint32 item_hash = item->hash;
@@ -157,12 +129,12 @@ static SDL_HashItem *find_item(const SDL_HashTable *ht, const void *key, Uint32
return NULL;
}
if (item_hash == hash && ht->keymatch(item->key, key, ht->data)) {
if (item_hash == hash && ht->keymatch(ht->userdata, item->key, key)) {
return item;
}
Uint32 item_probe_len = item->probe_len;
HT_ASSERT(item_probe_len == get_probe_length(item_hash & hash_mask, (Uint32)(item - table), hash_mask + 1));
SDL_assert(item_probe_len == get_probe_length(item_hash & hash_mask, (Uint32)(item - table), hash_mask + 1));
if (*probe_len > item_probe_len) {
return NULL;
@@ -185,23 +157,23 @@ static SDL_HashItem *find_first_item(const SDL_HashTable *ht, const void *key, U
static SDL_HashItem *insert_item(SDL_HashItem *item_to_insert, SDL_HashItem *table, Uint32 hash_mask, Uint32 *max_probe_len_ptr)
{
const Uint32 num_buckets = hash_mask + 1;
Uint32 idx = item_to_insert->hash & hash_mask;
SDL_HashItem temp_item, *target = NULL;
Uint32 num_buckets = hash_mask + 1;
SDL_HashItem *target = NULL;
SDL_HashItem temp_item;
for (;;) {
while (true) {
SDL_HashItem *candidate = table + idx;
if (!candidate->live) {
// Found an empty slot. Put it here and we're done.
*candidate = *item_to_insert;
if (target == NULL) {
target = candidate;
}
Uint32 probe_len = get_probe_length(candidate->hash & hash_mask, idx, num_buckets);
const Uint32 probe_len = get_probe_length(candidate->hash & hash_mask, idx, num_buckets);
candidate->probe_len = probe_len;
if (*max_probe_len_ptr < probe_len) {
@@ -211,9 +183,9 @@ static SDL_HashItem *insert_item(SDL_HashItem *item_to_insert, SDL_HashItem *tab
break;
}
Uint32 candidate_probe_len = candidate->probe_len;
HT_ASSERT(candidate_probe_len == get_probe_length(candidate->hash & hash_mask, idx, num_buckets));
Uint32 new_probe_len = get_probe_length(item_to_insert->hash & hash_mask, idx, num_buckets);
const Uint32 candidate_probe_len = candidate->probe_len;
SDL_assert(candidate_probe_len == get_probe_length(candidate->hash & hash_mask, idx, num_buckets));
const Uint32 new_probe_len = get_probe_length(item_to_insert->hash & hash_mask, idx, num_buckets);
if (candidate_probe_len < new_probe_len) {
// Robin Hood hashing: the item at idx has a better probe length than our item would at this position.
@@ -229,7 +201,7 @@ static SDL_HashItem *insert_item(SDL_HashItem *item_to_insert, SDL_HashItem *tab
*item_to_insert = temp_item;
HT_ASSERT(new_probe_len == get_probe_length(candidate->hash & hash_mask, idx, num_buckets));
SDL_assert(new_probe_len == get_probe_length(candidate->hash & hash_mask, idx, num_buckets));
candidate->probe_len = new_probe_len;
if (*max_probe_len_ptr < new_probe_len) {
@@ -245,17 +217,19 @@ static SDL_HashItem *insert_item(SDL_HashItem *item_to_insert, SDL_HashItem *tab
static void delete_item(SDL_HashTable *ht, SDL_HashItem *item)
{
Uint32 hash_mask = ht->hash_mask;
const Uint32 hash_mask = ht->hash_mask;
SDL_HashItem *table = ht->table;
if (ht->nuke) {
ht->nuke(item->key, item->value, ht->data);
if (ht->destroy) {
ht->destroy(ht->userdata, item->key, item->value);
}
SDL_assert(ht->num_occupied_slots > 0);
ht->num_occupied_slots--;
Uint32 idx = (Uint32)(item - ht->table);
for (;;) {
while (true) {
idx = (idx + 1) & hash_mask;
SDL_HashItem *next_item = table + idx;
@@ -266,22 +240,23 @@ static void delete_item(SDL_HashTable *ht, SDL_HashItem *item)
*item = *next_item;
item->probe_len -= 1;
HT_ASSERT(item->probe_len < ht->max_probe_len);
SDL_assert(item->probe_len < ht->max_probe_len);
item = next_item;
}
}
static bool resize(SDL_HashTable *ht, Uint32 new_size)
{
SDL_HashItem *old_table = ht->table;
Uint32 old_size = ht->hash_mask + 1;
Uint32 new_hash_mask = new_size - 1;
const Uint32 new_hash_mask = new_size - 1;
SDL_HashItem *new_table = SDL_calloc(new_size, sizeof(*new_table));
if (!new_table) {
return false;
}
SDL_HashItem *old_table = ht->table;
const Uint32 old_size = ht->hash_mask + 1;
ht->max_probe_len = 0;
ht->hash_mask = new_hash_mask;
ht->table = new_table;
@@ -299,14 +274,14 @@ static bool resize(SDL_HashTable *ht, Uint32 new_size)
static bool maybe_resize(SDL_HashTable *ht)
{
Uint32 capacity = ht->hash_mask + 1;
const Uint32 capacity = ht->hash_mask + 1;
if (capacity >= MAX_HASHTABLE_SIZE) {
return false;
}
Uint32 max_load_factor = 217; // range: 0-255; 217 is roughly 85%
Uint32 resize_threshold = (Uint32)((max_load_factor * (Uint64)capacity) >> 8);
const Uint32 max_load_factor = 217; // range: 0-255; 217 is roughly 85%
const Uint32 resize_threshold = (Uint32)((max_load_factor * (Uint64)capacity) >> 8);
if (ht->num_occupied_slots > resize_threshold) {
return resize(ht, capacity * 2);
@@ -315,28 +290,30 @@ static bool maybe_resize(SDL_HashTable *ht)
return true;
}
bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *value)
bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *value, bool replace)
{
SDL_HashItem *item;
Uint32 hash;
if (!table) {
return SDL_InvalidParamError("table");
}
bool result = false;
if (!table) {
return false;
}
if (table->lock) {
SDL_LockRWLockForWriting(table->lock);
}
hash = calc_hash(table, key);
item = find_first_item(table, key, hash);
const Uint32 hash = calc_hash(table, key);
SDL_HashItem *item = find_first_item(table, key, hash);
bool do_insert = true;
if (item && !table->stackable) {
// Allow overwrites, this might have been inserted on another thread
if (item) {
if (replace) {
delete_item(table, item);
} else {
SDL_SetError("key already exists and replace is disabled");
do_insert = false;
}
}
if (do_insert) {
SDL_HashItem new_item;
new_item.key = key;
new_item.value = value;
@@ -348,39 +325,31 @@ bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *
if (!maybe_resize(table)) {
table->num_occupied_slots--;
goto done;
}
} else {
// This never returns NULL
insert_item(&new_item, table->table, table->hash_mask, &table->max_probe_len);
result = true;
done:
if (table->lock) {
SDL_UnlockRWLock(table->lock);
}
}
SDL_UnlockRWLock(table->lock);
return result;
}
bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const void **value)
{
Uint32 hash;
SDL_HashItem *i;
bool result = false;
if (!table) {
if (value) {
*value = NULL;
}
return false;
return SDL_InvalidParamError("table");
}
if (table->lock) {
SDL_LockRWLockForReading(table->lock);
}
hash = calc_hash(table, key);
i = find_first_item(table, key, hash);
bool result = false;
const Uint32 hash = calc_hash(table, key);
SDL_HashItem *i = find_first_item(table, key, hash);
if (i) {
if (value) {
*value = i->value;
@@ -388,156 +357,91 @@ bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const void
result = true;
}
if (table->lock) {
SDL_UnlockRWLock(table->lock);
}
return result;
}
bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key)
{
Uint32 hash;
SDL_HashItem *item;
bool result = false;
if (!table) {
return false;
return SDL_InvalidParamError("table");
}
if (table->lock) {
SDL_LockRWLockForWriting(table->lock);
}
// FIXME: what to do for stacking hashtables?
// The original code removes just one item.
// This hashtable happens to preserve the insertion order of multi-value keys,
// so deleting the first one will always delete the least-recently inserted one.
// But maybe it makes more sense to remove all matching items?
hash = calc_hash(table, key);
item = find_first_item(table, key, hash);
if (!item) {
goto done;
}
bool result = false;
const Uint32 hash = calc_hash(table, key);
SDL_HashItem *item = find_first_item(table, key, hash);
if (item) {
delete_item(table, item);
result = true;
done:
if (table->lock) {
SDL_UnlockRWLock(table->lock);
}
SDL_UnlockRWLock(table->lock);
return result;
}
bool SDL_IterateHashTableKey(const SDL_HashTable *table, const void *key, const void **_value, void **iter)
bool SDL_IterateHashTable(const SDL_HashTable *table, SDL_HashTableIterateCallback callback, void *userdata)
{
SDL_HashItem *item = (SDL_HashItem *)*iter;
if (!table) {
return false;
return SDL_InvalidParamError("table");
} else if (!callback) {
return SDL_InvalidParamError("callback");
}
Uint32 i, probe_len, hash;
if (item) {
HT_ASSERT(item >= table->table);
HT_ASSERT(item < table->table + (table->hash_mask + 1));
hash = item->hash;
probe_len = item->probe_len + 1;
i = ((Uint32)(item - table->table) + 1) & table->hash_mask;
item = table->table + i;
} else {
hash = calc_hash(table, key);
i = hash & table->hash_mask;
probe_len = 0;
}
item = find_item(table, key, hash, &i, &probe_len);
if (!item) {
*_value = NULL;
return false;
}
*_value = item->value;
*iter = item;
return true;
}
bool SDL_IterateHashTable(const SDL_HashTable *table, const void **_key, const void **_value, void **iter)
{
SDL_HashItem *item = (SDL_HashItem *)*iter;
if (!table) {
return false;
}
if (!item) {
item = table->table;
} else {
item++;
}
HT_ASSERT(item >= table->table);
SDL_LockRWLockForReading(table->lock);
SDL_HashItem *end = table->table + (table->hash_mask + 1);
Uint32 num_iterated = 0;
while (item < end && !item->live) {
++item;
for (SDL_HashItem *item = table->table; item < end; item++) {
if (item->live) {
if (!callback(userdata, table, item->key, item->value)) {
break; // callback requested iteration stop.
} else if (++num_iterated >= table->num_occupied_slots) {
break; // we can drop out early because we've seen all the live items.
}
}
}
HT_ASSERT(item <= end);
if (item == end) {
if (_key) {
*_key = NULL;
}
if (_value) {
*_value = NULL;
}
return false;
}
if (_key) {
*_key = item->key;
}
if (_value) {
*_value = item->value;
}
*iter = item;
SDL_UnlockRWLock(table->lock);
return true;
}
bool SDL_HashTableEmpty(SDL_HashTable *table)
{
return !(table && table->num_occupied_slots);
if (!table) {
return SDL_InvalidParamError("table");
}
static void nuke_all(SDL_HashTable *table)
SDL_LockRWLockForReading(table->lock);
const bool retval = (table->num_occupied_slots == 0);
SDL_UnlockRWLock(table->lock);
return retval;
}
static void destroy_all(SDL_HashTable *table)
{
void *data = table->data;
SDL_HashDestroyCallback destroy = table->destroy;
if (destroy) {
void *userdata = table->userdata;
SDL_HashItem *end = table->table + (table->hash_mask + 1);
SDL_HashItem *i;
for (i = table->table; i < end; ++i) {
for (SDL_HashItem *i = table->table; i < end; ++i) {
if (i->live) {
table->nuke(i->key, i->value, data);
i->live = false;
destroy(userdata, i->key, i->value);
}
}
}
}
void SDL_EmptyHashTable(SDL_HashTable *table)
void SDL_ClearHashTable(SDL_HashTable *table)
{
if (table) {
SDL_LockRWLockForWriting(table->lock);
{
if (table->nuke) {
nuke_all(table);
}
destroy_all(table);
SDL_memset(table->table, 0, sizeof(*table->table) * (table->hash_mask + 1));
table->num_occupied_slots = 0;
}
@@ -548,9 +452,10 @@ void SDL_EmptyHashTable(SDL_HashTable *table)
void SDL_DestroyHashTable(SDL_HashTable *table)
{
if (table) {
SDL_EmptyHashTable(table);
destroy_all(table);
if (table->lock) {
SDL_DestroyRWLock(table->lock);
}
SDL_free(table->table);
SDL_free(table);
}
@@ -566,26 +471,26 @@ static SDL_INLINE Uint32 hash_string_djbxor(const char *str, size_t len)
return hash;
}
Uint32 SDL_HashPointer(const void *key, void *unused)
Uint32 SDL_HashPointer(void *unused, const void *key)
{
(void)unused;
return SDL_murmur3_32(&key, sizeof(key), 0);
}
bool SDL_KeyMatchPointer(const void *a, const void *b, void *unused)
bool SDL_KeyMatchPointer(void *unused, const void *a, const void *b)
{
(void)unused;
return (a == b);
}
Uint32 SDL_HashString(const void *key, void *unused)
Uint32 SDL_HashString(void *unused, const void *key)
{
(void)unused;
const char *str = (const char *)key;
return hash_string_djbxor(str, SDL_strlen(str));
}
bool SDL_KeyMatchString(const void *a, const void *b, void *unused)
bool SDL_KeyMatchString(void *unused, const void *a, const void *b)
{
const char *a_string = (const char *)a;
const char *b_string = (const char *)b;
@@ -604,26 +509,33 @@ bool SDL_KeyMatchString(const void *a, const void *b, void *unused)
// We assume we can fit the ID in the key directly
SDL_COMPILE_TIME_ASSERT(SDL_HashID_KeySize, sizeof(Uint32) <= sizeof(const void *));
Uint32 SDL_HashID(const void *key, void *unused)
Uint32 SDL_HashID(void *unused, const void *key)
{
(void)unused;
return (Uint32)(uintptr_t)key;
}
bool SDL_KeyMatchID(const void *a, const void *b, void *unused)
bool SDL_KeyMatchID(void *unused, const void *a, const void *b)
{
(void)unused;
return (a == b);
}
void SDL_NukeFreeKey(const void *key, const void *value, void *unused)
void SDL_DestroyHashKeyAndValue(void *unused, const void *key, const void *value)
{
(void)unused;
SDL_free((void *)key);
SDL_free((void *)value);
}
void SDL_DestroyHashKey(void *unused, const void *key, const void *value)
{
(void)value;
(void)unused;
SDL_free((void *)key);
}
void SDL_NukeFreeValue(const void *key, const void *value, void *unused)
void SDL_DestroyHashValue(void *unused, const void *key, const void *value)
{
(void)key;
(void)unused;

View File

@@ -18,61 +18,616 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* this is over-documented because it was almost a public API. Leaving the
full docs here in case it _does_ become public some day. */
/* WIKI CATEGORY: HashTable */
/**
* # CategoryHashTable
*
* SDL offers a hash table implementation, as a convenience for C code that
* needs efficient organization and access of arbitrary data.
*
* Hash tables are a popular data structure, designed to make it quick to
* store and look up arbitrary data. Data is stored with an associated "key."
* While one would look up an element of an array with an index, a hash table
* uses a unique key to find an element later.
*
* A key can be anything, as long as its unique and in a format that the table
* understands. For example, it's popular to use strings as keys: the key
* might be a username, and it is used to lookup account information for that
* user, etc.
*
* Hash tables are named because they "hash" their keys down into simple
* integers that can be used to efficiently organize and access the associated
* data.
*
* As this is a C API, there is one generic interface that is intended to work
* with different data types. This can be a little awkward to set up, but is
* easy to use after that.
*
* Hashtables are generated by a call to SDL_CreateHashTable(). This function
* requires several callbacks to be provided (for hashing keys, comparing
* entries, and cleaning up entries when removed). These are necessary to
* allow the hash to manage any arbitrary data type.
*
* Once a hash table is created, the common tasks are inserting data into the
* table, (SDL_InsertIntoHashTable), looking up previously inserted data
* (SDL_FindInHashTable), and removing data (SDL_RemoveFromHashTable and
* SDL_ClearHashTable). Less common but still useful is the ability to
* iterate through all the items in the table (SDL_IterateHashTable).
*
* The underlying hash table implementation is always subject to change, but
* at the time of writing, it uses open addressing and Robin Hood hashing.
* The technical details are explained [here](https://github.com/libsdl-org/SDL/pull/10897).
*
* Hashtables keep an SDL_RWLock internally, so multiple threads can perform
* hash lookups in parallel, while changes to the table will safely serialize
* access between threads.
*
* SDL provides a layer on top of this hash table implementation that might be
* more pleasant to use. SDL_PropertiesID maps a string to arbitrary data of
* various types in the same table, which could be both easier to use and more
* flexible. Refer to [CategoryProperties](CategoryProperties) for details.
*/
#ifndef SDL_hashtable_h_
#define SDL_hashtable_h_
// this is not (currently) a public API. But maybe it should be!
#include <SDL3/SDL_stdinc.h>
struct SDL_HashTable;
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* The opaque type that represents a hash table.
*
* This is hidden behind an opaque pointer because not only does the table
* need to store arbitrary data types, but the hash table implementation may
* change in the future.
*
* \since This struct is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
typedef struct SDL_HashTable SDL_HashTable;
typedef Uint32 (*SDL_HashTable_HashFn)(const void *key, void *data);
typedef bool (*SDL_HashTable_KeyMatchFn)(const void *a, const void *b, void *data);
typedef void (*SDL_HashTable_NukeFn)(const void *key, const void *value, void *data);
extern SDL_HashTable *SDL_CreateHashTable(void *data,
Uint32 num_buckets,
SDL_HashTable_HashFn hashfn,
SDL_HashTable_KeyMatchFn keymatchfn,
SDL_HashTable_NukeFn nukefn,
/**
* A function pointer representing a hash table hashing callback.
*
* This is called by SDL_HashTable when it needs to look up a key in
* its dataset. It generates a hash value from that key, and then uses that
* value as a basis for an index into an internal array.
*
* There are no rules on what hashing algorithm is used, so long as it
* can produce a reliable 32-bit value from `key`, and ideally distributes
* those values well across the 32-bit value space. The quality of a
* hashing algorithm is directly related to how well a hash table performs.
*
* Hashing can be a complicated subject, and often times what works best
* for one dataset will be suboptimal for another. There is a good discussion
* of the field [on Wikipedia](https://en.wikipedia.org/wiki/Hash_function).
*
* Also: do you _need_ to write a hashing function? SDL provides generic
* functions for strings (SDL_HashString), generic integer IDs (SDL_HashID),
* and generic pointers (SDL_HashPointer). Often you should use one of these
* before writing your own.
*
* \param userdata what was passed as `userdata` to SDL_CreateHashTable().
* \param key the key to be hashed.
* \returns a 32-bit value that represents a hash of `key`.
*
* \threadsafety This function must be thread safe if the hash table is used
* from multiple threads at the same time.
*
* \since This datatype is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
* \sa SDL_HashString
* \sa SDL_HashID
* \sa SDL_HashPointer
*/
typedef Uint32 (SDLCALL *SDL_HashCallback)(void *userdata, const void *key);
/**
* A function pointer representing a hash table matching callback.
*
* This is called by SDL_HashTable when it needs to look up a key in its
* dataset. After hashing the key, it looks for items stored in relation to
* that hash value. Since there can be more than one item found through the
* same hash value, this function verifies a specific value is actually
* correct before choosing it.
*
* So this function needs to compare the keys at `a` and `b` and decide if
* they are actually the same.
*
* For example, if the keys are C strings, this function might just be:
*
* ```c
* return (SDL_strcmp((const char *) a, const char *b) == 0);`
* ```
*
* Also: do you _need_ to write a matching function? SDL provides generic
* functions for strings (SDL_KeyMatchString), generic integer IDs
* (SDL_KeyMatchID), and generic pointers (SDL_KeyMatchPointer). Often you
* should use one of these before writing your own.
*
* \param userdata what was passed as `userdata` to SDL_CreateHashTable().
* \param a the first key to be compared.
* \param b the second key to be compared.
* \returns true if two keys are identical, false otherwise.
*
* \threadsafety This function must be thread safe if the hash table is used
* from multiple threads at the same time.
*
* \since This datatype is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
typedef bool (SDLCALL *SDL_HashKeyMatchCallback)(void *userdata, const void *a, const void *b);
/**
* A function pointer representing a hash table cleanup callback.
*
* This is called by SDL_HashTable when removing items from the hash, or
* destroying the hash table. It is used to optionally deallocate the
* key/value pairs.
*
* This is not required to do anything, if all the data in the table is
* static or POD data, but it can also do more than a simple free: for
* example, if the hash table is storing open files, it can close them here.
* It can also free only the key or only the value; it depends on what the
* hash table contains.
*
* \param userdata what was passed as `userdata` to SDL_CreateHashTable().
* \param key the key to deallocate.
* \param value the value to deallocate.
*
* \threadsafety This function must be thread safe if the hash table is used
* from multiple threads at the same time.
*
* \since This datatype is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
typedef void (SDLCALL *SDL_HashDestroyCallback)(void *userdata, const void *key, const void *value);
/**
* A function pointer representing a hash table iterator callback.
*
* This function is called once for each key/value pair to be considered
* when iterating a hash table.
*
* Iteration continues as long as there are more items to examine and this
* callback continues to return true.
*
* Do not attempt to modify the hash table during this callback, as it will
* cause incorrect behavior and possibly crashes.
*
* \param userdata what was passed as `userdata` to an iterator function.
* \param table the hash table being iterated.
* \param key the current key being iterated.
* \param value the current value being iterated.
* \returns true to keep iterating, false to stop iteration.
*
* \threadsafety A read lock is held during iteration, so other threads can
* still access the the hash table, but threads attempting to
* make changes will be blocked until iteration completes. If
* this is a concern, do as little in the callback as possible
* and finish iteration quickly.
*
* \since This datatype is available since SDL 3.4.0.
*
* \sa SDL_IterateHashTable
*/
typedef bool (SDLCALL *SDL_HashTableIterateCallback)(void *userdata, const SDL_HashTable *table, const void *key, const void *value);
/**
* Create a new hash table.
*
* To deal with different datatypes and needs of the caller, hash tables
* require several callbacks that deal with some specifics: how to hash a key,
* how to compare a key for equality, and how to clean up keys and values.
* SDL provides a few generic functions that can be used for these callbacks:
*
* - SDL_HashString and SDL_KeyMatchString for C strings.
* - SDL_HashPointer and SDL_KeyMatchPointer for generic pointers.
* - SDL_HashID and SDL_KeyMatchID for generic (possibly small) integers.
*
* Oftentimes, these are all you need for any hash table, but depending on
* your dataset, custom implementations might make more sense.
*
* You can specify an estimate of the number of items expected to be stored
* in the table, which can help make the table run more efficiently. The table
* will preallocate resources to accomodate this number of items, which is
* most useful if you intend to fill the table with a lot of data right after
* creating it. Otherwise, it might make more sense to specify the _minimum_
* you expect the table to hold and let it grow as necessary from there. This
* number is only a hint, and the table will be able to handle any amount of
* data--as long as the system doesn't run out of resources--so a perfect
* answer is not required. A value of 0 signifies no guess at all, and the
* table will start small and reallocate as necessary; often this is the
* correct thing to do.
*
* !!! FIXME: add note about `threadsafe` here. And update `threadsafety` tags.
* !!! FIXME: note that `threadsafe` tables can't be recursively locked, so
* !!! FIXME: you can't use `destroy` callbacks that might end up relocking.
*
* Note that SDL provides a higher-level option built on its hash tables:
* SDL_PropertiesID lets you map strings to various datatypes, and this
* might be easier to use. It only allows strings for keys, however. Those are
* created with SDL_CreateProperties().
*
* The returned hash table should be destroyed with SDL_DestroyHashTable()
* when no longer needed.
*
* \param estimated_capacity the approximate maximum number of items to be held
* in the hash table, or 0 for no estimate.
* \param threadsafe true to create an internal rwlock for this table.
* \param hash the function to use to hash keys.
* \param keymatch the function to use to compare keys.
* \param destroy the function to use to clean up keys and values, may be NULL.
* \param userdata a pointer that is passed to the callbacks.
* \returns a newly-created hash table, or NULL if there was an error; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_DestroyHashTable
*/
extern SDL_HashTable * SDL_CreateHashTable(int estimated_capacity,
bool threadsafe,
bool stackable);
SDL_HashCallback hash,
SDL_HashKeyMatchCallback keymatch,
SDL_HashDestroyCallback destroy,
void *userdata);
// This function is thread-safe if the hashtable was created with threadsafe = true
extern void SDL_EmptyHashTable(SDL_HashTable *table);
// This function is not thread-safe.
/**
* Destroy a hash table.
*
* This will call the hash table's SDL_HashDestroyCallback for each item in
* the table, removing all inserted items, before deallocating the table
* itself.
*
* The table becomes invalid once this function is called, and no other thread
* should be accessing this table once this function has started.
*
* \param table the hash table to destroy.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*/
extern void SDL_DestroyHashTable(SDL_HashTable *table);
// This function is thread-safe if the hashtable was created with threadsafe = true
extern bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *value);
/**
* Add an item to a hash table.
*
* All keys in the table must be unique. If attempting to insert a key that
* already exists in the hash table, what will be done depends on the
* `replace` value:
*
* - If `replace` is false, this function will return false without modifying
* the table.
* - If `replace` is true, SDL will remove the previous item first, so the new
* value is the only one associated with that key. This will call the hash
* table's SDL_HashDestroyCallback for the previous item.
*
* \param table the hash table to insert into.
* \param key the key of the new item to insert.
* \param value the value of the new item to insert.
* \param replace true if a duplicate key should replace the previous value.
* \returns true if the new item was inserted, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*/
extern bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *value, bool replace);
// This function is thread-safe if the hashtable was created with threadsafe = true
/**
* Look up an item in a hash table.
*
* On return, the value associated with `key` is stored to `*value`.
* If the key does not exist in the table, `*value` will be set to NULL.
*
* It is legal for `value` to be NULL, to not retrieve the key's value. In
* this case, the return value is still useful for reporting if the key exists
* in the table at all.
*
* \param table the hash table to search.
* \param key the key to search for in the table.
* \param value the found value will be stored here. Can be NULL.
* \returns true if key exists in the table, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_InsertIntoHashTable
*/
extern bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const void **value);
/**
* Remove an item from a hash table.
*
* If there is an item that matches `key`, it is removed from the table. This
* will call the hash table's SDL_HashDestroyCallback for the item to be
* removed.
*
* \param table the hash table to remove from.
* \param key the key of the item to remove from the table.
* \returns true if a key was removed, false if the key was not found.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*/
extern bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key);
// This function is thread-safe if the hashtable was created with threadsafe = true
extern bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const void **_value);
/**
* Remove all items in a hash table.
*
* This will call the hash table's SDL_HashDestroyCallback for each item in
* the table, removing all inserted items.
*
* When this function returns, the hash table will be empty.
*
* \param table the hash table to clear.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*/
extern void SDL_ClearHashTable(SDL_HashTable *table);
// This function is thread-safe if the hashtable was created with threadsafe = true
/**
* Check if any items are currently stored in a hash table.
*
* If there are no items stored (the table is completely empty), this will
* return true.
*
* \param table the hash table to check.
* \returns true if the table is completely empty, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_ClearHashTable
*/
extern bool SDL_HashTableEmpty(SDL_HashTable *table);
// iterate all values for a specific key. This only makes sense if the hash is stackable. If not-stackable, just use SDL_FindInHashTable().
// This function is not thread-safe, you should use external locking if you use this function
extern bool SDL_IterateHashTableKey(const SDL_HashTable *table, const void *key, const void **_value, void **iter);
/**
* Iterate all key/value pairs in a hash table.
*
* This function will call `callback` once for each key/value pair in the
* table, until either all pairs have been presented to the callback, or the
* callback has returned false to signal it is done.
*
* There is no guarantee what order results will be returned in.
*
* \param table the hash table to iterate.
* \param callback the function pointer to call for each value.
* \param userdata a pointer that is passed to `callback`.
* \returns true if iteration happened, false if not (bogus parameter, etc).
*
* \since This function is available since SDL 3.4.0.
*/
extern bool SDL_IterateHashTable(const SDL_HashTable *table, SDL_HashTableIterateCallback callback, void *userdata);
// iterate all key/value pairs in a hash (stackable hashes can have duplicate keys with multiple values).
// This function is not thread-safe, you should use external locking if you use this function
extern bool SDL_IterateHashTable(const SDL_HashTable *table, const void **_key, const void **_value, void **iter);
extern Uint32 SDL_HashPointer(const void *key, void *unused);
extern bool SDL_KeyMatchPointer(const void *a, const void *b, void *unused);
/* Helper functions for SDL_CreateHashTable callbacks... */
extern Uint32 SDL_HashString(const void *key, void *unused);
extern bool SDL_KeyMatchString(const void *a, const void *b, void *unused);
/**
* Generate a hash from a generic pointer.
*
* The key is intended to be a unique pointer to any datatype.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of keys to be used with the hash table.
*
* Note that the implementation may change in the future; do not expect
* the results to be stable vs future SDL releases. Use this in a hash table
* in the current process and don't store them to disk for the future.
*
* \param unused this parameter is ignored.
* \param key the key to hash as a generic pointer.
* \returns a 32-bit hash of the key.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern Uint32 SDL_HashPointer(void *unused, const void *key);
extern Uint32 SDL_HashID(const void *key, void *unused);
extern bool SDL_KeyMatchID(const void *a, const void *b, void *unused);
/**
* Compare two generic pointers as hash table keys.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of keys to be used with the hash table.
*
* \param unused this parameter is ignored.
* \param a the first generic pointer to compare.
* \param b the second generic pointer to compare.
* \returns true if the pointers are the same, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern bool SDL_KeyMatchPointer(void *unused, const void *a, const void *b);
extern void SDL_NukeFreeKey(const void *key, const void *value, void *unused);
extern void SDL_NukeFreeValue(const void *key, const void *value, void *unused);
/**
* Generate a hash from a C string.
*
* The key is intended to be a NULL-terminated string, in UTF-8 format.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of keys to be used with the hash table.
*
* Note that the implementation may change in the future; do not expect
* the results to be stable vs future SDL releases. Use this in a hash table
* in the current process and don't store them to disk for the future.
*
* \param unused this parameter is ignored.
* \param key the key to hash as a generic pointer.
* \returns a 32-bit hash of the key.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern Uint32 SDL_HashString(void *unused, const void *key);
#endif // SDL_hashtable_h_
/**
* Compare two C strings as hash table keys.
*
* Strings will be compared in a case-sensitive manner. More specifically,
* they'll be compared as NULL-terminated arrays of bytes.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of keys to be used with the hash table.
*
* \param unused this parameter is ignored.
* \param a the first string to compare.
* \param b the second string to compare.
* \returns true if the strings are the same, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern bool SDL_KeyMatchString(void *unused, const void *a, const void *b);
/**
* Generate a hash from an integer ID.
*
* The key is intended to a unique integer, possibly within a small range.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of keys to be used with the hash table.
*
* Note that the implementation may change in the future; do not expect
* the results to be stable vs future SDL releases. Use this in a hash table
* in the current process and don't store them to disk for the future.
*
* \param unused this parameter is ignored.
* \param key the key to hash as a generic pointer.
* \returns a 32-bit hash of the key.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern Uint32 SDL_HashID(void *unused, const void *key);
/**
* Compare two integer IDs as hash table keys.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of keys to be used with the hash table.
*
* \param unused this parameter is ignored.
* \param a the first ID to compare.
* \param b the second ID to compare.
* \returns true if the IDs are the same, false otherwise.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern bool SDL_KeyMatchID(void *unused, const void *a, const void *b);
/**
* Free both the key and value pointers of a hash table item.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of data to be used with the hash table.
*
* This literally calls `SDL_free(key);` and `SDL_free(value);`.
*
* \param unused this parameter is ignored.
* \param key the key to be destroyed.
* \param value the value to be destroyed.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern void SDL_DestroyHashKeyAndValue(void *unused, const void *key, const void *value);
/**
* Free just the value pointer of a hash table item.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of data to be used with the hash table.
*
* This literally calls `SDL_free(key);` and leaves `value` alone.
*
* \param unused this parameter is ignored.
* \param key the key to be destroyed.
* \param value the value to be destroyed.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern void SDL_DestroyHashKey(void *unused, const void *key, const void *value);
/**
* Free just the value pointer of a hash table item.
*
* This is intended to be used as one of the callbacks to SDL_CreateHashTable,
* if this is useful to the type of data to be used with the hash table.
*
* This literally calls `SDL_free(value);` and leaves `key` alone.
*
* \param unused this parameter is ignored.
* \param key the key to be destroyed.
* \param value the value to be destroyed.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateHashTable
*/
extern void SDL_DestroyHashValue(void *unused, const void *key, const void *value);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_hashtable_h_ */

View File

@@ -22,6 +22,10 @@
#include "SDL_hints_c.h"
#ifdef SDL_PLATFORM_ANDROID
#include "core/android/SDL_android.h"
#endif
typedef struct SDL_HintWatch
{
SDL_HintCallback callback;
@@ -147,6 +151,13 @@ bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriori
}
}
#ifdef SDL_PLATFORM_ANDROID
if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) {
// Special handling for this hint, which needs to persist outside the normal application flow
Android_SetAllowRecreateActivity(SDL_GetStringBoolean(value, false));
}
#endif // SDL_PLATFORM_ANDROID
SDL_UnlockProperties(hints);
return result;
@@ -185,6 +196,17 @@ bool SDL_ResetHint(const char *name)
result = true;
}
#ifdef SDL_PLATFORM_ANDROID
if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) {
// Special handling for this hint, which needs to persist outside the normal application flow
if (env) {
Android_SetAllowRecreateActivity(SDL_GetStringBoolean(env, false));
} else {
Android_SetAllowRecreateActivity(false);
}
}
#endif // SDL_PLATFORM_ANDROID
SDL_UnlockProperties(hints);
return result;
@@ -210,6 +232,17 @@ static void SDLCALL ResetHintsCallback(void *userdata, SDL_PropertiesID hints, c
SDL_free(hint->value);
hint->value = NULL;
hint->priority = SDL_HINT_DEFAULT;
#ifdef SDL_PLATFORM_ANDROID
if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) {
// Special handling for this hint, which needs to persist outside the normal application flow
if (env) {
Android_SetAllowRecreateActivity(SDL_GetStringBoolean(env, false));
} else {
Android_SetAllowRecreateActivity(false);
}
}
#endif // SDL_PLATFORM_ANDROID
}
void SDL_ResetHints(void)

View File

@@ -191,6 +191,11 @@
#define SDL_VIDEO_RENDER_SW 1
#endif
/* STB image conversion */
#if !defined(SDL_HAVE_STB) && !defined(SDL_LEAN_AND_MEAN)
#define SDL_HAVE_STB 1
#endif
/* YUV formats
- handling of YUV surfaces
- blitting and conversion functions */
@@ -198,6 +203,17 @@
#define SDL_HAVE_YUV 1
#endif
#ifdef SDL_CAMERA_DISABLED
#undef SDL_CAMERA_DRIVER_ANDROID
#undef SDL_CAMERA_DRIVER_COREMEDIA
#undef SDL_CAMERA_DRIVER_DUMMY
#undef SDL_CAMERA_DRIVER_EMSCRIPTEN
#undef SDL_CAMERA_DRIVER_MEDIAFOUNDATION
#undef SDL_CAMERA_DRIVER_PIPEWIRE
#undef SDL_CAMERA_DRIVER_V4L2
#undef SDL_CAMERA_DRIVER_VITA
#endif
#ifdef SDL_RENDER_DISABLED
#undef SDL_VIDEO_RENDER_SW
#undef SDL_VIDEO_RENDER_D3D
@@ -249,6 +265,12 @@ extern "C" {
#include "SDL_utils_c.h"
#include "SDL_hashtable.h"
#define PUSH_SDL_ERROR() \
{ char *_error = SDL_strdup(SDL_GetError());
#define POP_SDL_ERROR() \
SDL_SetError("%s", _error); SDL_free(_error); }
// Do any initialization that needs to happen before threads are started
extern void SDL_InitMainThread(void);

View File

@@ -76,7 +76,7 @@ static void SDL_FreePropertyWithCleanup(const void *key, const void *value, void
SDL_free((void *)value);
}
static void SDL_FreeProperty(const void *key, const void *value, void *data)
static void SDLCALL SDL_FreeProperty(void *data, const void *key, const void *value)
{
SDL_FreePropertyWithCleanup(key, value, data, true);
}
@@ -84,14 +84,8 @@ static void SDL_FreeProperty(const void *key, const void *value, void *data)
static void SDL_FreeProperties(SDL_Properties *properties)
{
if (properties) {
if (properties->props) {
SDL_DestroyHashTable(properties->props);
properties->props = NULL;
}
if (properties->lock) {
SDL_DestroyMutex(properties->lock);
properties->lock = NULL;
}
SDL_free(properties);
}
}
@@ -102,18 +96,16 @@ bool SDL_InitProperties(void)
return true;
}
SDL_properties = SDL_CreateHashTable(NULL, 16, SDL_HashID, SDL_KeyMatchID, NULL, true, false);
if (!SDL_properties) {
goto error;
SDL_properties = SDL_CreateHashTable(0, true, SDL_HashID, SDL_KeyMatchID, NULL, NULL);
const bool initialized = (SDL_properties != NULL);
SDL_SetInitialized(&SDL_properties_init, initialized);
return initialized;
}
SDL_SetInitialized(&SDL_properties_init, true);
return true;
error:
SDL_SetInitialized(&SDL_properties_init, true);
SDL_QuitProperties();
return false;
static bool SDLCALL FreeOneProperties(void *userdata, const SDL_HashTable *table, const void *key, const void *value)
{
SDL_FreeProperties((SDL_Properties *)value);
return true; // keep iterating.
}
void SDL_QuitProperties(void)
@@ -131,17 +123,13 @@ void SDL_QuitProperties(void)
SDL_DestroyProperties(props);
}
if (SDL_properties) {
void *iter;
const void *key, *value;
iter = NULL;
while (SDL_IterateHashTable(SDL_properties, &key, &value, &iter)) {
SDL_FreeProperties((SDL_Properties *)value);
}
SDL_DestroyHashTable(SDL_properties);
// this can't just DestroyHashTable with SDL_FreeProperties as the destructor, because
// other destructors under this might cause use to attempt a recursive lock on SDL_properties,
// which isn't allowed with rwlocks. So manually iterate and free everything.
SDL_HashTable *properties = SDL_properties;
SDL_properties = NULL;
}
SDL_IterateHashTable(properties, FreeOneProperties, NULL);
SDL_DestroyHashTable(properties);
SDL_SetInitialized(&SDL_properties_init, false);
}
@@ -167,55 +155,101 @@ SDL_PropertiesID SDL_GetGlobalProperties(void)
SDL_PropertiesID SDL_CreateProperties(void)
{
SDL_PropertiesID props = 0;
SDL_Properties *properties = NULL;
bool inserted = false;
if (!SDL_CheckInitProperties()) {
return 0;
}
properties = (SDL_Properties *)SDL_calloc(1, sizeof(*properties));
SDL_Properties *properties = (SDL_Properties *)SDL_calloc(1, sizeof(*properties));
if (!properties) {
goto error;
}
properties->props = SDL_CreateHashTable(NULL, 4, SDL_HashString, SDL_KeyMatchString, SDL_FreeProperty, false, false);
if (!properties->props) {
goto error;
return 0;
}
// If this fails we'll continue without it.
properties->lock = SDL_CreateMutex();
if (!properties->lock) {
SDL_free(properties);
return 0;
}
for ( ; ; ) {
properties->props = SDL_CreateHashTable(0, false, SDL_HashString, SDL_KeyMatchString, SDL_FreeProperty, NULL);
if (!properties->props) {
SDL_DestroyMutex(properties->lock);
SDL_free(properties);
return 0;
}
SDL_PropertiesID props = 0;
while (true) {
props = (SDL_GetAtomicU32(&SDL_last_properties_id) + 1);
if (props == 0) {
continue;
}
if (SDL_CompareAndSwapAtomicU32(&SDL_last_properties_id, props - 1, props)) {
} else if (SDL_CompareAndSwapAtomicU32(&SDL_last_properties_id, props - 1, props)) {
break;
}
}
if (SDL_InsertIntoHashTable(SDL_properties, (const void *)(uintptr_t)props, properties)) {
inserted = true;
}
if (inserted) {
// All done!
return props;
}
SDL_assert(!SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, NULL)); // should NOT be in the hash table already.
error:
if (!SDL_InsertIntoHashTable(SDL_properties, (const void *)(uintptr_t)props, properties, false)) {
SDL_FreeProperties(properties);
return 0;
}
return props; // All done!
}
typedef struct CopyOnePropertyData
{
SDL_Properties *dst_properties;
bool result;
} CopyOnePropertyData;
static bool SDLCALL CopyOneProperty(void *userdata, const SDL_HashTable *table, const void *key, const void *value)
{
const SDL_Property *src_property = (const SDL_Property *)value;
if (src_property->cleanup) {
// Can't copy properties with cleanup functions, we don't know how to duplicate the data
return true; // keep iterating.
}
CopyOnePropertyData *data = (CopyOnePropertyData *) userdata;
SDL_Properties *dst_properties = data->dst_properties;
const char *src_name = (const char *)key;
SDL_Property *dst_property;
char *dst_name = SDL_strdup(src_name);
if (!dst_name) {
data->result = false;
return true; // keep iterating (I guess...?)
}
dst_property = (SDL_Property *)SDL_malloc(sizeof(*dst_property));
if (!dst_property) {
SDL_free(dst_name);
data->result = false;
return true; // keep iterating (I guess...?)
}
SDL_copyp(dst_property, src_property);
if (src_property->type == SDL_PROPERTY_TYPE_STRING) {
dst_property->value.string_value = SDL_strdup(src_property->value.string_value);
if (!dst_property->value.string_value) {
SDL_free(dst_name);
SDL_free(dst_property);
data->result = false;
return true; // keep iterating (I guess...?)
}
}
if (!SDL_InsertIntoHashTable(dst_properties->props, dst_name, dst_property, true)) {
SDL_FreePropertyWithCleanup(dst_name, dst_property, NULL, false);
data->result = false;
}
return true; // keep iterating.
}
bool SDL_CopyProperties(SDL_PropertiesID src, SDL_PropertiesID dst)
{
SDL_Properties *src_properties = NULL;
SDL_Properties *dst_properties = NULL;
bool result = true;
if (!src) {
return SDL_InvalidParamError("src");
}
@@ -223,55 +257,25 @@ bool SDL_CopyProperties(SDL_PropertiesID src, SDL_PropertiesID dst)
return SDL_InvalidParamError("dst");
}
SDL_Properties *src_properties = NULL;
SDL_Properties *dst_properties = NULL;
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)src, (const void **)&src_properties);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)dst, (const void **)&dst_properties);
if (!src_properties) {
return SDL_InvalidParamError("src");
}
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)dst, (const void **)&dst_properties);
if (!dst_properties) {
return SDL_InvalidParamError("dst");
}
bool result = true;
SDL_LockMutex(src_properties->lock);
SDL_LockMutex(dst_properties->lock);
{
void *iter;
const void *key, *value;
iter = NULL;
while (SDL_IterateHashTable(src_properties->props, &key, &value, &iter)) {
const char *src_name = (const char *)key;
const SDL_Property *src_property = (const SDL_Property *)value;
char *dst_name;
SDL_Property *dst_property;
if (src_property->cleanup) {
// Can't copy properties with cleanup functions, we don't know how to duplicate the data
continue;
}
SDL_RemoveFromHashTable(dst_properties->props, src_name);
dst_name = SDL_strdup(src_name);
if (!dst_name) {
result = false;
continue;
}
dst_property = (SDL_Property *)SDL_malloc(sizeof(*dst_property));
if (!dst_property) {
SDL_free(dst_name);
result = false;
continue;
}
SDL_copyp(dst_property, src_property);
if (src_property->type == SDL_PROPERTY_TYPE_STRING) {
dst_property->value.string_value = SDL_strdup(src_property->value.string_value);
}
if (!SDL_InsertIntoHashTable(dst_properties->props, dst_name, dst_property)) {
SDL_FreePropertyWithCleanup(dst_name, dst_property, NULL, false);
result = false;
}
}
CopyOnePropertyData data = { dst_properties, true };
SDL_IterateHashTable(src_properties->props, CopyOneProperty, &data);
result = data.result;
}
SDL_UnlockMutex(dst_properties->lock);
SDL_UnlockMutex(src_properties->lock);
@@ -337,7 +341,7 @@ static bool SDL_PrivateSetProperty(SDL_PropertiesID props, const char *name, SDL
SDL_RemoveFromHashTable(properties->props, name);
if (property) {
char *key = SDL_strdup(name);
if (!SDL_InsertIntoHashTable(properties->props, key, property)) {
if (!key || !SDL_InsertIntoHashTable(properties->props, key, property, false)) {
SDL_FreePropertyWithCleanup(key, property, NULL, true);
result = false;
}
@@ -518,10 +522,9 @@ void *SDL_GetPointerProperty(SDL_PropertiesID props, const char *name, void *def
return value;
}
/* Note that taking the lock here only guarantees that we won't read the
* hashtable while it's being modified. The value itself can easily be
* freed from another thread after it is returned here.
*/
// Note that taking the lock here only guarantees that we won't read the
// hashtable while it's being modified. The value itself can easily be
// freed from another thread after it is returned here.
SDL_LockMutex(properties->lock);
{
SDL_Property *property = NULL;
@@ -731,6 +734,23 @@ bool SDL_ClearProperty(SDL_PropertiesID props, const char *name)
return SDL_PrivateSetProperty(props, name, NULL);
}
typedef struct EnumerateOnePropertyData
{
SDL_EnumeratePropertiesCallback callback;
void *userdata;
SDL_PropertiesID props;
} EnumerateOnePropertyData;
static bool SDLCALL EnumerateOneProperty(void *userdata, const SDL_HashTable *table, const void *key, const void *value)
{
(void) table;
(void) value;
const EnumerateOnePropertyData *data = (const EnumerateOnePropertyData *) userdata;
data->callback(data->userdata, data->props, (const char *)key);
return true; // keep iterating.
}
bool SDL_EnumerateProperties(SDL_PropertiesID props, SDL_EnumeratePropertiesCallback callback, void *userdata)
{
SDL_Properties *properties = NULL;
@@ -749,13 +769,8 @@ bool SDL_EnumerateProperties(SDL_PropertiesID props, SDL_EnumeratePropertiesCall
SDL_LockMutex(properties->lock);
{
void *iter;
const void *key, *value;
iter = NULL;
while (SDL_IterateHashTable(properties->props, &key, &value, &iter)) {
callback(userdata, props, (const char *)key);
}
EnumerateOnePropertyData data = { callback, userdata, props };
SDL_IterateHashTable(properties->props, EnumerateOneProperty, &data);
}
SDL_UnlockMutex(properties->lock);
@@ -796,14 +811,14 @@ bool SDL_DumpProperties(SDL_PropertiesID props)
void SDL_DestroyProperties(SDL_PropertiesID props)
{
if (props) {
// this can't just use RemoveFromHashTable with SDL_FreeProperties as the destructor, because
// other destructors under this might cause use to attempt a recursive lock on SDL_properties,
// which isn't allowed with rwlocks. So manually look it up and remove/free it.
SDL_Properties *properties = NULL;
if (!props) {
return;
}
if (SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties)) {
SDL_FreeProperties(properties);
SDL_RemoveFromHashTable(SDL_properties, (const void *)(uintptr_t)props);
}
}
}

View File

@@ -24,6 +24,9 @@
#include <unistd.h>
#endif
#include "joystick/SDL_joystick_c.h" // For SDL_GetGamepadTypeFromVIDPID()
// Common utility functions that aren't in the public API
int SDL_powerof2(int x)
@@ -135,12 +138,12 @@ Uint32 SDL_GetNextObjectID(void)
static SDL_InitState SDL_objects_init;
static SDL_HashTable *SDL_objects;
static Uint32 SDL_HashObject(const void *key, void *unused)
static Uint32 SDLCALL SDL_HashObject(void *unused, const void *key)
{
return (Uint32)(uintptr_t)key;
}
static bool SDL_KeyMatchObject(const void *a, const void *b, void *unused)
static bool SDL_KeyMatchObject(void *unused, const void *a, const void *b)
{
return (a == b);
}
@@ -149,16 +152,17 @@ void SDL_SetObjectValid(void *object, SDL_ObjectType type, bool valid)
{
SDL_assert(object != NULL);
if (valid && SDL_ShouldInit(&SDL_objects_init)) {
SDL_objects = SDL_CreateHashTable(NULL, 32, SDL_HashObject, SDL_KeyMatchObject, NULL, true, false);
if (!SDL_objects) {
SDL_SetInitialized(&SDL_objects_init, false);
if (SDL_ShouldInit(&SDL_objects_init)) {
SDL_objects = SDL_CreateHashTable(0, true, SDL_HashObject, SDL_KeyMatchObject, NULL, NULL);
const bool initialized = (SDL_objects != NULL);
SDL_SetInitialized(&SDL_objects_init, initialized);
if (!initialized) {
return;
}
SDL_SetInitialized(&SDL_objects_init, true);
}
if (valid) {
SDL_InsertIntoHashTable(SDL_objects, object, (void *)(uintptr_t)type);
SDL_InsertIntoHashTable(SDL_objects, object, (void *)(uintptr_t)type, true);
} else {
SDL_RemoveFromHashTable(SDL_objects, object);
}
@@ -178,75 +182,65 @@ bool SDL_ObjectValid(void *object, SDL_ObjectType type)
return (((SDL_ObjectType)(uintptr_t)object_type) == type);
}
typedef struct GetOneObjectData
{
const SDL_ObjectType type;
void **objects;
const int count;
int num_objects;
} GetOneObjectData;
static bool SDLCALL GetOneObject(void *userdata, const SDL_HashTable *table, const void *object, const void *object_type)
{
GetOneObjectData *data = (GetOneObjectData *) userdata;
if ((SDL_ObjectType)(uintptr_t)object_type == data->type) {
if (data->num_objects < data->count) {
data->objects[data->num_objects] = (void *)object;
}
++data->num_objects;
}
return true; // keep iterating.
}
int SDL_GetObjects(SDL_ObjectType type, void **objects, int count)
{
const void *object, *object_type;
void *iter = NULL;
int num_objects = 0;
while (SDL_IterateHashTable(SDL_objects, &object, &object_type, &iter)) {
if ((SDL_ObjectType)(uintptr_t)object_type == type) {
if (num_objects < count) {
objects[num_objects] = (void *)object;
GetOneObjectData data = { type, objects, count, 0 };
SDL_IterateHashTable(SDL_objects, GetOneObject, &data);
return data.num_objects;
}
++num_objects;
static bool SDLCALL LogOneLeakedObject(void *userdata, const SDL_HashTable *table, const void *object, const void *object_type)
{
const char *type = "unknown object";
switch ((SDL_ObjectType)(uintptr_t)object_type) {
#define SDLOBJTYPECASE(typ, name) case SDL_OBJECT_TYPE_##typ: type = name; break
SDLOBJTYPECASE(WINDOW, "SDL_Window");
SDLOBJTYPECASE(RENDERER, "SDL_Renderer");
SDLOBJTYPECASE(TEXTURE, "SDL_Texture");
SDLOBJTYPECASE(JOYSTICK, "SDL_Joystick");
SDLOBJTYPECASE(GAMEPAD, "SDL_Gamepad");
SDLOBJTYPECASE(HAPTIC, "SDL_Haptic");
SDLOBJTYPECASE(SENSOR, "SDL_Sensor");
SDLOBJTYPECASE(HIDAPI_DEVICE, "hidapi device");
SDLOBJTYPECASE(HIDAPI_JOYSTICK, "hidapi joystick");
SDLOBJTYPECASE(THREAD, "thread");
SDLOBJTYPECASE(TRAY, "SDL_Tray");
#undef SDLOBJTYPECASE
default: break;
}
}
return num_objects;
SDL_Log("Leaked %s (%p)", type, object);
return true; // keep iterating.
}
void SDL_SetObjectsInvalid(void)
{
if (SDL_ShouldQuit(&SDL_objects_init)) {
// Log any leaked objects
const void *object, *object_type;
void *iter = NULL;
while (SDL_IterateHashTable(SDL_objects, &object, &object_type, &iter)) {
const char *type;
switch ((SDL_ObjectType)(uintptr_t)object_type) {
case SDL_OBJECT_TYPE_WINDOW:
type = "SDL_Window";
break;
case SDL_OBJECT_TYPE_RENDERER:
type = "SDL_Renderer";
break;
case SDL_OBJECT_TYPE_TEXTURE:
type = "SDL_Texture";
break;
case SDL_OBJECT_TYPE_JOYSTICK:
type = "SDL_Joystick";
break;
case SDL_OBJECT_TYPE_GAMEPAD:
type = "SDL_Gamepad";
break;
case SDL_OBJECT_TYPE_HAPTIC:
type = "SDL_Haptic";
break;
case SDL_OBJECT_TYPE_SENSOR:
type = "SDL_Sensor";
break;
case SDL_OBJECT_TYPE_HIDAPI_DEVICE:
type = "hidapi device";
break;
case SDL_OBJECT_TYPE_HIDAPI_JOYSTICK:
type = "hidapi joystick";
break;
case SDL_OBJECT_TYPE_THREAD:
type = "thread";
break;
case SDL_OBJECT_TYPE_TRAY:
type = "SDL_Tray";
break;
default:
type = "unknown object";
break;
}
SDL_Log("Leaked %s (%p)", type, object);
}
SDL_IterateHashTable(SDL_objects, LogOneLeakedObject, NULL);
SDL_assert(SDL_HashTableEmpty(SDL_objects));
SDL_DestroyHashTable(SDL_objects);
SDL_objects = NULL;
SDL_SetInitialized(&SDL_objects_init, false);
}
}
@@ -384,7 +378,7 @@ const char *SDL_GetPersistentString(const char *string)
SDL_HashTable *strings = (SDL_HashTable *)SDL_GetTLS(&SDL_string_storage);
if (!strings) {
strings = SDL_CreateHashTable(NULL, 32, SDL_HashString, SDL_KeyMatchString, SDL_NukeFreeValue, false, false);
strings = SDL_CreateHashTable(0, false, SDL_HashString, SDL_KeyMatchString, SDL_DestroyHashValue, NULL);
if (!strings) {
return NULL;
}
@@ -400,8 +394,161 @@ const char *SDL_GetPersistentString(const char *string)
}
// If the hash table insert fails, at least we can return the string we allocated
SDL_InsertIntoHashTable(strings, new_string, new_string);
SDL_InsertIntoHashTable(strings, new_string, new_string, false);
result = new_string;
}
return result;
}
static int PrefixMatch(const char *a, const char *b)
{
int matchlen = 0;
// Fixes the "HORI HORl Taiko No Tatsujin Drum Controller"
if (SDL_strncmp(a, "HORI ", 5) == 0 && SDL_strncmp(b, "HORl ", 5) == 0) {
return 5;
}
while (*a && *b) {
if (SDL_tolower((unsigned char)*a++) == SDL_tolower((unsigned char)*b++)) {
++matchlen;
} else {
break;
}
}
return matchlen;
}
char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name, const char *default_name)
{
static struct
{
const char *prefix;
const char *replacement;
} replacements[] = {
{ "8BitDo Tech Ltd", "8BitDo" },
{ "ASTRO Gaming", "ASTRO" },
{ "Bensussen Deutsch & Associates,Inc.(BDA)", "BDA" },
{ "Guangzhou Chicken Run Network Technology Co., Ltd.", "GameSir" },
{ "HORI CO.,LTD.", "HORI" },
{ "HORI CO.,LTD", "HORI" },
{ "Mad Catz Inc.", "Mad Catz" },
{ "Nintendo Co., Ltd.", "Nintendo" },
{ "NVIDIA Corporation ", "" },
{ "Performance Designed Products", "PDP" },
{ "QANBA USA, LLC", "Qanba" },
{ "QANBA USA,LLC", "Qanba" },
{ "Unknown ", "" },
};
char *name = NULL;
size_t i, len;
if (!vendor_name) {
vendor_name = "";
}
if (!product_name) {
product_name = "";
}
while (*vendor_name == ' ') {
++vendor_name;
}
while (*product_name == ' ') {
++product_name;
}
if (*vendor_name && *product_name) {
len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
name = (char *)SDL_malloc(len);
if (name) {
(void)SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
}
} else if (*product_name) {
name = SDL_strdup(product_name);
} else if (vendor || product) {
// Couldn't find a controller name, try to give it one based on device type
switch (SDL_GetGamepadTypeFromVIDPID(vendor, product, NULL, true)) {
case SDL_GAMEPAD_TYPE_XBOX360:
name = SDL_strdup("Xbox 360 Controller");
break;
case SDL_GAMEPAD_TYPE_XBOXONE:
name = SDL_strdup("Xbox One Controller");
break;
case SDL_GAMEPAD_TYPE_PS3:
name = SDL_strdup("PS3 Controller");
break;
case SDL_GAMEPAD_TYPE_PS4:
name = SDL_strdup("PS4 Controller");
break;
case SDL_GAMEPAD_TYPE_PS5:
name = SDL_strdup("DualSense Wireless Controller");
break;
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
name = SDL_strdup("Nintendo Switch Pro Controller");
break;
default:
len = (6 + 1 + 6 + 1);
name = (char *)SDL_malloc(len);
if (name) {
(void)SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
}
break;
}
} else if (default_name) {
name = SDL_strdup(default_name);
}
if (!name) {
return NULL;
}
// Trim trailing whitespace
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
// continue
}
name[len] = '\0';
// Compress duplicate spaces
for (i = 0; i < (len - 1);) {
if (name[i] == ' ' && name[i + 1] == ' ') {
SDL_memmove(&name[i], &name[i + 1], (len - i));
--len;
} else {
++i;
}
}
// Perform any manufacturer replacements
for (i = 0; i < SDL_arraysize(replacements); ++i) {
size_t prefixlen = SDL_strlen(replacements[i].prefix);
if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
size_t replacementlen = SDL_strlen(replacements[i].replacement);
if (replacementlen <= prefixlen) {
SDL_memcpy(name, replacements[i].replacement, replacementlen);
SDL_memmove(name + replacementlen, name + prefixlen, (len - prefixlen) + 1);
len -= (prefixlen - replacementlen);
} else {
// FIXME: Need to handle the expand case by reallocating the string
}
break;
}
}
/* Remove duplicate manufacturer or product in the name
* e.g. Razer Razer Raiju Tournament Edition Wired
*/
for (i = 1; i < (len - 1); ++i) {
int matchlen = PrefixMatch(name, &name[i]);
while (matchlen > 0) {
if (name[matchlen] == ' ' || name[matchlen] == '-') {
SDL_memmove(name, name + matchlen + 1, len - matchlen);
break;
}
--matchlen;
}
if (matchlen > 0) {
// We matched the manufacturer's name and removed it
break;
}
}
return name;
}

View File

@@ -73,4 +73,6 @@ extern void SDL_SetObjectsInvalid(void);
extern const char *SDL_GetPersistentString(const char *string);
extern char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name, const char *default_name);
#endif // SDL_utils_h_

View File

@@ -136,6 +136,7 @@ const char *SDL_GetAudioDriver(int index)
if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
return deduped_bootstrap[index]->name;
}
SDL_InvalidParamError("index");
return NULL;
}
@@ -409,6 +410,7 @@ static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid,
SDL_LockRWLockForReading(current_audio.device_hash_lock);
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev);
if (logdev) {
SDL_assert(logdev->instance_id == devid);
device = logdev->physical_device;
SDL_assert(device != NULL);
RefPhysicalAudioDevice(device); // reference it, in case the logical device migrates to a new default.
@@ -458,6 +460,7 @@ static SDL_AudioDevice *ObtainPhysicalAudioDevice(SDL_AudioDeviceID devid) // !
} else {
SDL_LockRWLockForReading(current_audio.device_hash_lock);
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
SDL_assert(device->instance_id == devid);
SDL_UnlockRWLock(current_audio.device_hash_lock);
if (!device) {
@@ -650,7 +653,7 @@ static SDL_AudioDevice *CreatePhysicalAudioDevice(const char *name, bool recordi
device->instance_id = AssignAudioDeviceInstanceId(recording, /*islogical=*/false);
SDL_LockRWLockForWriting(current_audio.device_hash_lock);
if (SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) device->instance_id, device)) {
if (SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) device->instance_id, device, false)) {
SDL_AddAtomicInt(device_count, 1);
} else {
SDL_DestroyCondition(device->close_cond);
@@ -864,50 +867,48 @@ static void CompleteAudioEntryPoints(void)
#undef FILL_STUB
}
static SDL_AudioDevice *GetFirstAddedAudioDevice(const bool recording)
typedef struct FindLowestDeviceIDData
{
SDL_AudioDeviceID highest = (SDL_AudioDeviceID) SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK; // According to AssignAudioDeviceInstanceId, nothing can have a value this large.
SDL_AudioDevice *result = NULL;
const bool recording;
SDL_AudioDeviceID highest;
SDL_AudioDevice *result;
} FindLowestDeviceIDData;
// (Device IDs increase as new devices are added, so the first device added has the lowest SDL_AudioDeviceID value.)
SDL_LockRWLockForReading(current_audio.device_hash_lock);
const void *key;
const void *value;
void *iter = NULL;
while (SDL_IterateHashTable(current_audio.device_hash, &key, &value, &iter)) {
static bool SDLCALL FindLowestDeviceID(void *userdata, const SDL_HashTable *table, const void *key, const void *value)
{
FindLowestDeviceIDData *data = (FindLowestDeviceIDData *) userdata;
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
// bit #0 of devid is set for playback devices and unset for recording.
// bit #1 of devid is set for physical devices and unset for logical.
const bool devid_recording = !(devid & (1 << 0));
const bool isphysical = !!(devid & (1 << 1));
if (isphysical && (devid_recording == recording) && (devid < highest)) {
highest = devid;
result = (SDL_AudioDevice *) value;
if (isphysical && (devid_recording == data->recording) && (devid < data->highest)) {
data->highest = devid;
data->result = (SDL_AudioDevice *) value;
SDL_assert(data->result->instance_id == devid);
}
return true; // keep iterating.
}
static SDL_AudioDevice *GetFirstAddedAudioDevice(const bool recording)
{
const SDL_AudioDeviceID highest = SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK; // According to AssignAudioDeviceInstanceId, nothing can have a value this large.
// (Device IDs increase as new devices are added, so the first device added has the lowest SDL_AudioDeviceID value.)
FindLowestDeviceIDData data = { recording, highest, NULL };
SDL_LockRWLockForReading(current_audio.device_hash_lock);
SDL_IterateHashTable(current_audio.device_hash, FindLowestDeviceID, &data);
SDL_UnlockRWLock(current_audio.device_hash_lock);
return result;
return data.result;
}
static Uint32 HashAudioDeviceID(const void *key, void *data)
static Uint32 SDLCALL HashAudioDeviceID(void *userdata, const void *key)
{
// shift right 2, to dump the first two bits, since these are flags
// (recording vs playback, logical vs physical) and the rest are unique incrementing integers.
return ((Uint32) ((uintptr_t) key)) >> 2;
}
static bool MatchAudioDeviceID(const void *a, const void *b, void *data)
{
return (a == b);
}
static void NukeAudioDeviceHashItem(const void *key, const void *value, void *data)
{
// no-op, keys and values in this hashtable are treated as Plain Old Data and don't get freed here.
}
// !!! FIXME: the video subsystem does SDL_VideoInit, not SDL_InitVideo. Make this match.
bool SDL_InitAudio(const char *driver_name)
{
@@ -926,7 +927,7 @@ bool SDL_InitAudio(const char *driver_name)
return false;
}
SDL_HashTable *device_hash = SDL_CreateHashTable(NULL, 8, HashAudioDeviceID, MatchAudioDeviceID, NukeAudioDeviceHashItem, false, false);
SDL_HashTable *device_hash = SDL_CreateHashTable(0, false, HashAudioDeviceID, SDL_KeyMatchID, NULL, NULL);
if (!device_hash) {
SDL_DestroyRWLock(device_hash_lock);
return false;
@@ -964,7 +965,7 @@ bool SDL_InitAudio(const char *driver_name)
}
for (int i = 0; bootstrap[i]; ++i) {
if (SDL_strcasecmp(bootstrap[i]->name, driver_attempt) == 0) {
if (!bootstrap[i]->is_preferred && SDL_strcasecmp(bootstrap[i]->name, driver_attempt) == 0) {
tried_to_init = true;
SDL_zero(current_audio);
current_audio.pending_events_tail = &current_audio.pending_events;
@@ -1047,6 +1048,20 @@ bool SDL_InitAudio(const char *driver_name)
return true;
}
static bool SDLCALL DestroyOnePhysicalAudioDevice(void *userdata, const SDL_HashTable *table, const void *key, const void *value)
{
// bit #1 of devid is set for physical devices and unset for logical.
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
const bool isphysical = !!(devid & (1<<1));
if (isphysical) {
SDL_AudioDevice *dev = (SDL_AudioDevice *) value;
SDL_assert(dev->instance_id == devid);
DestroyPhysicalAudioDevice(dev);
}
return true; // keep iterating.
}
void SDL_QuitAudio(void)
{
if (!current_audio.name) { // not initialized?!
@@ -1076,17 +1091,7 @@ void SDL_QuitAudio(void)
SDL_free(i);
}
const void *key;
const void *value;
void *iter = NULL;
while (SDL_IterateHashTable(device_hash, &key, &value, &iter)) {
// bit #1 of devid is set for physical devices and unset for logical.
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
const bool isphysical = !!(devid & (1<<1));
if (isphysical) {
DestroyPhysicalAudioDevice((SDL_AudioDevice *) value);
}
}
SDL_IterateHashTable(device_hash, DestroyOnePhysicalAudioDevice, NULL);
// Free the driver data
current_audio.impl.Deinitialize();
@@ -1148,7 +1153,10 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
// We should have updated this elsewhere if the format changed!
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &device->spec, NULL, NULL));
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
const int br = SDL_GetAtomicInt(&logdev->paused) ? 0 : SDL_GetAudioStreamDataAdjustGain(stream, device_buffer, buffer_size, logdev->gain);
if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow.
failed = true;
SDL_memset(device_buffer, device->silence_value, buffer_size); // just supply silence to the device before we die.
@@ -1190,6 +1198,8 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
// We should have updated this elsewhere if the format changed!
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &outspec, NULL, NULL));
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
/* this will hold a lock on `stream` while getting. We don't explicitly lock the streams
for iterating here because the binding linked list can only change while the device lock is held.
(we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind
@@ -1257,11 +1267,11 @@ static int SDLCALL PlaybackAudioThread(void *devicep) // thread entry point
SDL_assert(!device->recording);
SDL_PlaybackAudioThreadSetup(device);
do {
while (SDL_PlaybackAudioThreadIterate(device)) {
if (!device->WaitDevice(device)) {
SDL_AudioDeviceDisconnected(device); // doh. (but don't break out of the loop, just be a zombie for now!)
}
} while (SDL_PlaybackAudioThreadIterate(device));
}
SDL_PlaybackAudioThreadShutdown(device);
return 0;
@@ -1325,6 +1335,7 @@ bool SDL_RecordingAudioThreadIterate(SDL_AudioDevice *device)
SDL_assert(stream->src_spec.format == ((logdev->postmix || (logdev->gain != 1.0f)) ? SDL_AUDIO_F32 : device->spec.format));
SDL_assert(stream->src_spec.channels == device->spec.channels);
SDL_assert(stream->src_spec.freq == device->spec.freq);
SDL_assert(stream->dst_spec.format != SDL_AUDIO_UNKNOWN);
void *final_buf = output_buffer;
@@ -1383,6 +1394,35 @@ static int SDLCALL RecordingAudioThread(void *devicep) // thread entry point
return 0;
}
typedef struct CountAudioDevicesData
{
int devs_seen;
int devs_skipped;
const int num_devices;
SDL_AudioDeviceID *result;
const bool recording;
} CountAudioDevicesData;
static bool SDLCALL CountAudioDevices(void *userdata, const SDL_HashTable *table, const void *key, const void *value)
{
CountAudioDevicesData *data = (CountAudioDevicesData *) userdata;
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
// bit #0 of devid is set for playback devices and unset for recording.
// bit #1 of devid is set for physical devices and unset for logical.
const bool devid_recording = !(devid & (1<<0));
const bool isphysical = !!(devid & (1<<1));
if (isphysical && (devid_recording == data->recording)) {
SDL_assert(data->devs_seen < data->num_devices);
SDL_AudioDevice *device = (SDL_AudioDevice *) value; // this is normally risky, but we hold the device_hash_lock here.
const bool zombie = SDL_GetAtomicInt(&device->zombie) != 0;
if (zombie) {
data->devs_skipped++;
} else {
data->result[data->devs_seen++] = devid;
}
}
return true; // keep iterating.
}
static SDL_AudioDeviceID *GetAudioDevices(int *count, bool recording)
{
@@ -1395,24 +1435,11 @@ static SDL_AudioDeviceID *GetAudioDevices(int *count, bool recording)
num_devices = SDL_GetAtomicInt(recording ? &current_audio.recording_device_count : &current_audio.playback_device_count);
result = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID));
if (result) {
int devs_seen = 0;
const void *key;
const void *value;
void *iter = NULL;
while (SDL_IterateHashTable(current_audio.device_hash, &key, &value, &iter)) {
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
// bit #0 of devid is set for playback devices and unset for recording.
// bit #1 of devid is set for physical devices and unset for logical.
const bool devid_recording = !(devid & (1<<0));
const bool isphysical = !!(devid & (1<<1));
if (isphysical && (devid_recording == recording)) {
SDL_assert(devs_seen < num_devices);
result[devs_seen++] = devid;
}
}
SDL_assert(devs_seen == num_devices);
result[devs_seen] = 0; // null-terminated.
CountAudioDevicesData data = { 0, 0, num_devices, result, recording };
SDL_IterateHashTable(current_audio.device_hash, CountAudioDevices, &data);
SDL_assert((data.devs_seen + data.devs_skipped) == num_devices);
num_devices = data.devs_seen; // might be less if we skipped any.
result[num_devices] = 0; // null-terminated.
}
}
SDL_UnlockRWLock(current_audio.device_hash_lock);
@@ -1440,7 +1467,31 @@ SDL_AudioDeviceID *SDL_GetAudioRecordingDevices(int *count)
return GetAudioDevices(count, true);
}
typedef struct FindAudioDeviceByCallbackData
{
bool (*callback)(SDL_AudioDevice *device, void *userdata);
void *userdata;
SDL_AudioDevice *retval;
} FindAudioDeviceByCallbackData;
static bool SDLCALL FindAudioDeviceByCallback(void *userdata, const SDL_HashTable *table, const void *key, const void *value)
{
FindAudioDeviceByCallbackData *data = (FindAudioDeviceByCallbackData *) userdata;
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
// bit #1 of devid is set for physical devices and unset for logical.
const bool isphysical = !!(devid & (1<<1));
if (isphysical) {
SDL_AudioDevice *device = (SDL_AudioDevice *) value;
if (data->callback(device, data->userdata)) { // found it?
data->retval = device;
SDL_assert(data->retval->instance_id == devid);
return false; // stop iterating, we found it.
}
}
return true; // keep iterating.
}
// !!! FIXME: SDL convention is for userdata to come first in the callback's params. Fix this at some point.
SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByCallback(bool (*callback)(SDL_AudioDevice *device, void *userdata), void *userdata)
{
if (!SDL_GetCurrentAudioDriver()) {
@@ -1448,27 +1499,16 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByCallback(bool (*callback)(SDL_Audi
return NULL;
}
const void *key;
const void *value;
void *iter = NULL;
FindAudioDeviceByCallbackData data = { callback, userdata, NULL };
SDL_LockRWLockForReading(current_audio.device_hash_lock);
while (SDL_IterateHashTable(current_audio.device_hash, &key, &value, &iter)) {
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
// bit #1 of devid is set for physical devices and unset for logical.
const bool isphysical = !!(devid & (1<<1));
if (isphysical) {
SDL_AudioDevice *device = (SDL_AudioDevice *) value;
if (callback(device, userdata)) { // found it?
SDL_UnlockRWLock(current_audio.device_hash_lock);
return device;
}
}
}
SDL_IterateHashTable(current_audio.device_hash, FindAudioDeviceByCallback, &data);
SDL_UnlockRWLock(current_audio.device_hash_lock);
if (!data.retval) {
SDL_SetError("Device not found");
return NULL;
}
return data.retval;
}
static bool TestDeviceHandleCallback(SDL_AudioDevice *device, void *handle)
@@ -1483,12 +1523,33 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle)
const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
{
// bit #1 of devid is set for physical devices and unset for logical.
const bool islogical = !(devid & (1<<1));
const char *result = NULL;
SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid);
if (device) {
const void *vdev = NULL;
if (!SDL_GetCurrentAudioDriver()) {
SDL_SetError("Audio subsystem is not initialized");
} else {
// This does not call ObtainPhysicalAudioDevice() because the device's name never changes, so
// it doesn't have to lock the whole device. However, just to make sure the device pointer itself
// remains valid (in case the device is unplugged at the wrong moment), we hold the
// device_hash_lock while we copy the string.
SDL_LockRWLockForReading(current_audio.device_hash_lock);
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, &vdev);
if (!vdev) {
SDL_SetError("Invalid audio device instance ID");
} else if (islogical) {
const SDL_LogicalAudioDevice *logdev = (const SDL_LogicalAudioDevice *) vdev;
SDL_assert(logdev->instance_id == devid);
result = SDL_GetPersistentString(logdev->physical_device->name);
} else {
const SDL_AudioDevice *device = (const SDL_AudioDevice *) vdev;
SDL_assert(device->instance_id == devid);
result = SDL_GetPersistentString(device->name);
}
ReleaseAudioDevice(device);
SDL_UnlockRWLock(current_audio.device_hash_lock);
}
return result;
}
@@ -1520,8 +1581,10 @@ int *SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count)
SDL_AudioDevice *device = ObtainPhysicalAudioDeviceDefaultAllowed(devid);
if (device) {
channels = device->spec.channels;
if (channels > 0 && device->chmap) {
result = SDL_ChannelMapDup(device->chmap, channels);
}
}
ReleaseAudioDevice(device);
if (count) {
@@ -1696,13 +1759,18 @@ static bool OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec
SDL_copyp(&spec, inspec ? inspec : &device->default_spec);
PrepareAudioFormat(device->recording, &spec);
/* We allow the device format to change if it's better than the current settings (by various definitions of "better"). This prevents
something low quality, like an old game using S8/8000Hz audio, from ruining a music thing playing at CD quality that tries to open later.
(or some VoIP library that opens for mono output ruining your surround-sound game because it got there first).
/* We impose a simple minimum on device formats. This prevents something low quality, like an old game using S8/8000Hz audio,
from ruining a music thing playing at CD quality that tries to open later, or some VoIP library that opens for mono output
ruining your surround-sound game because it got there first.
These are just requests! The backend may change any of these values during OpenDevice method! */
device->spec.format = (SDL_AUDIO_BITSIZE(device->default_spec.format) >= SDL_AUDIO_BITSIZE(spec.format)) ? device->default_spec.format : spec.format;
device->spec.freq = SDL_max(device->default_spec.freq, spec.freq);
device->spec.channels = SDL_max(device->default_spec.channels, spec.channels);
const SDL_AudioFormat minimum_format = device->recording ? DEFAULT_AUDIO_RECORDING_FORMAT : DEFAULT_AUDIO_PLAYBACK_FORMAT;
const int minimum_channels = device->recording ? DEFAULT_AUDIO_RECORDING_CHANNELS : DEFAULT_AUDIO_PLAYBACK_CHANNELS;
const int minimum_freq = device->recording ? DEFAULT_AUDIO_RECORDING_FREQUENCY : DEFAULT_AUDIO_PLAYBACK_FREQUENCY;
device->spec.format = (SDL_AUDIO_BITSIZE(minimum_format) >= SDL_AUDIO_BITSIZE(spec.format)) ? minimum_format : spec.format;
device->spec.channels = SDL_max(minimum_channels, spec.channels);
device->spec.freq = SDL_max(minimum_freq, spec.freq);
device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq);
SDL_UpdatedAudioDeviceFormat(device); // start this off sane.
@@ -1794,7 +1862,7 @@ SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSp
if (result) {
SDL_LockRWLockForWriting(current_audio.device_hash_lock);
const bool inserted = SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) result, logdev);
const bool inserted = SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) result, logdev, false);
SDL_UnlockRWLock(current_audio.device_hash_lock);
if (!inserted) {
SDL_CloseAudioDevice(result);
@@ -1913,10 +1981,6 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
} else if (logdev->simplified) {
result = SDL_SetError("Cannot change stream bindings on device opened with SDL_OpenAudioDeviceStream");
} else {
// !!! FIXME: We'll set the device's side's format below, but maybe we should refuse to bind a stream if the app's side doesn't have a format set yet.
// !!! FIXME: Actually, why do we allow there to be an invalid format, again?
// make sure start of list is sane.
SDL_assert(!logdev->bound_streams || (logdev->bound_streams->prev_binding == NULL));
@@ -1951,9 +2015,17 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
if (result) {
// Now that everything is verified, chain everything together.
const bool recording = device->recording;
for (int i = 0; i < num_streams; i++) {
SDL_AudioStream *stream = streams[i];
if (stream) { // shouldn't be NULL, but just in case...
// if the stream never had its non-device-end format set, just set it to the device end's format.
if (recording && (stream->dst_spec.format == SDL_AUDIO_UNKNOWN)) {
SDL_copyp(&stream->dst_spec, &device->spec);
} else if (!recording && (stream->src_spec.format == SDL_AUDIO_UNKNOWN)) {
SDL_copyp(&stream->src_spec, &device->spec);
}
stream->bound_device = logdev;
stream->prev_binding = NULL;
stream->next_binding = logdev->bound_streams;

View File

@@ -444,7 +444,7 @@ static void SincTable(float *table, int len)
}
// Calculate Sinc(x/y), using a lookup table
static float Sinc(float *table, int x, int y)
static float Sinc(const float *table, int x, int y)
{
float s = table[x % y];
s = ((x / y) & 1) ? -s : s;
@@ -587,7 +587,18 @@ Sint64 SDL_GetResampleRate(int src_rate, int dst_rate)
SDL_assert(src_rate > 0);
SDL_assert(dst_rate > 0);
Sint64 sample_rate = ((Sint64)src_rate << 32) / (Sint64)dst_rate;
Sint64 numerator = (Sint64)src_rate << 32;
Sint64 denominator = (Sint64)dst_rate;
// Generally it's expected that `dst_frames = (src_frames * dst_rate) / src_rate`
// To match this as closely as possible without infinite precision, always round up the resample rate.
// For example, without rounding up, a sample ratio of 2:3 would have `sample_rate = 0xAAAAAAAA`
// After 3 frames, the position would be 0x1.FFFFFFFE, meaning we haven't fully consumed the second input frame.
// By rounding up to 0xAAAAAAAB, we would instead reach 0x2.00000001, fulling consuming the second frame.
// Technically you could say this is kicking the can 0x100000000 steps down the road, but I'm fine with that :)
// sample_rate = div_ceil(numerator, denominator)
Sint64 sample_rate = ((numerator - 1) / denominator) + 1;
SDL_assert(sample_rate > 0);
return sample_rate;
@@ -657,7 +668,7 @@ Sint64 SDL_GetResamplerOutputFrames(Sint64 input_frames, Sint64 resample_rate, S
}
// output_frames = div_ceil(input_offset, resample_rate)
Sint64 output_frames = (input_offset > 0) ? ((input_offset + resample_rate * 3 / 4) / resample_rate) : 0;
Sint64 output_frames = (input_offset > 0) ? ((input_offset - 1) / resample_rate) + 1 : 0;
*inout_resample_offset = (output_frames * resample_rate) - input_offset;

View File

@@ -22,6 +22,10 @@
#include "SDL_sysaudio.h"
#ifdef SDL_NEON_INTRINSICS
#include <fenv.h>
#endif
#define DIVBY2147483648 0.0000000004656612873077392578125f // 0x1p-31f
// start fallback scalar converters
@@ -527,9 +531,29 @@ static void SDL_TARGETING("ssse3") SDL_Convert_Swap32_SSSE3(Uint32* dst, const U
#endif
#ifdef SDL_NEON_INTRINSICS
// C99 requires that all code modifying floating point environment should
// be guarded by the STDC FENV_ACCESS pragma; otherwise, it's undefined
// behavior. However, the compiler support for this pragma is bad.
#if defined(__clang__)
#if __clang_major__ >= 12
#if defined(__aarch64__)
#pragma STDC FENV_ACCESS ON
#endif
#endif
#elif defined(_MSC_VER)
#pragma fenv_access (on)
#elif defined(__GNUC__)
// GCC does not support the pragma at all
#else
#pragma STDC FENV_ACCESS ON
#endif
static void SDL_Convert_S8_to_F32_NEON(float *dst, const Sint8 *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("S8", "F32 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
CONVERT_16_REV({
vst1_lane_f32(&dst[i], vcvt_n_f32_s32(vdup_n_s32(src[i]), 7), 0);
@@ -549,11 +573,14 @@ static void SDL_Convert_S8_to_F32_NEON(float *dst, const Sint8 *src, int num_sam
vst1q_f32(&dst[i + 8], floats2);
vst1q_f32(&dst[i + 12], floats3);
})
fesetenv(&fenv);
}
static void SDL_Convert_U8_to_F32_NEON(float *dst, const Uint8 *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("U8", "F32 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
uint8x16_t flipper = vdupq_n_u8(0x80);
@@ -575,11 +602,14 @@ static void SDL_Convert_U8_to_F32_NEON(float *dst, const Uint8 *src, int num_sam
vst1q_f32(&dst[i + 8], floats2);
vst1q_f32(&dst[i + 12], floats3);
})
fesetenv(&fenv);
}
static void SDL_Convert_S16_to_F32_NEON(float *dst, const Sint16 *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("S16", "F32 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
CONVERT_16_REV({
vst1_lane_f32(&dst[i], vcvt_n_f32_s32(vdup_n_s32(src[i]), 15), 0);
@@ -597,11 +627,14 @@ static void SDL_Convert_S16_to_F32_NEON(float *dst, const Sint16 *src, int num_s
vst1q_f32(&dst[i + 8], floats2);
vst1q_f32(&dst[i + 12], floats3);
})
fesetenv(&fenv);
}
static void SDL_Convert_S32_to_F32_NEON(float *dst, const Sint32 *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("S32", "F32 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
CONVERT_16_FWD({
vst1_lane_f32(&dst[i], vcvt_n_f32_s32(vld1_dup_s32(&src[i]), 31), 0);
@@ -621,11 +654,14 @@ static void SDL_Convert_S32_to_F32_NEON(float *dst, const Sint32 *src, int num_s
vst1q_f32(&dst[i + 8], floats2);
vst1q_f32(&dst[i + 12], floats3);
})
fesetenv(&fenv);
}
static void SDL_Convert_F32_to_S8_NEON(Sint8 *dst, const float *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("F32", "S8 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
CONVERT_16_FWD({
vst1_lane_s8(&dst[i], vreinterpret_s8_s32(vcvt_n_s32_f32(vld1_dup_f32(&src[i]), 31)), 3);
@@ -647,11 +683,14 @@ static void SDL_Convert_F32_to_S8_NEON(Sint8 *dst, const float *src, int num_sam
vst1q_s8(&dst[i], bytes);
})
fesetenv(&fenv);
}
static void SDL_Convert_F32_to_U8_NEON(Uint8 *dst, const float *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("F32", "U8 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
uint8x16_t flipper = vdupq_n_u8(0x80);
@@ -679,11 +718,14 @@ static void SDL_Convert_F32_to_U8_NEON(Uint8 *dst, const float *src, int num_sam
vst1q_u8(&dst[i], bytes);
})
fesetenv(&fenv);
}
static void SDL_Convert_F32_to_S16_NEON(Sint16 *dst, const float *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("F32", "S16 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
CONVERT_16_FWD({
vst1_lane_s16(&dst[i], vreinterpret_s16_s32(vcvt_n_s32_f32(vld1_dup_f32(&src[i]), 31)), 1);
@@ -704,11 +746,14 @@ static void SDL_Convert_F32_to_S16_NEON(Sint16 *dst, const float *src, int num_s
vst1q_s16(&dst[i], shorts0);
vst1q_s16(&dst[i + 8], shorts1);
})
fesetenv(&fenv);
}
static void SDL_Convert_F32_to_S32_NEON(Sint32 *dst, const float *src, int num_samples)
{
LOG_DEBUG_AUDIO_CONVERT("F32", "S32 (using NEON)");
fenv_t fenv;
feholdexcept(&fenv);
CONVERT_16_FWD({
vst1_lane_s32(&dst[i], vcvt_n_s32_f32(vld1_dup_f32(&src[i]), 31), 0);
@@ -728,6 +773,7 @@ static void SDL_Convert_F32_to_S32_NEON(Sint32 *dst, const float *src, int num_s
vst1q_s32(&dst[i + 8], ints2);
vst1q_s32(&dst[i + 12], ints3);
})
fesetenv(&fenv);
}
static void SDL_Convert_Swap16_NEON(Uint16* dst, const Uint16* src, int num_samples)
@@ -767,6 +813,21 @@ static void SDL_Convert_Swap32_NEON(Uint32* dst, const Uint32* src, int num_samp
vst1q_u8((Uint8*)&dst[i + 12], ints3);
})
}
#if defined(__clang__)
#if __clang_major__ >= 12
#if defined(__aarch64__)
#pragma STDC FENV_ACCESS DEFAULT
#endif
#endif
#elif defined(_MSC_VER)
#pragma fenv_access (off)
#elif defined(__GNUC__)
//
#else
#pragma STDC FENV_ACCESS DEFAULT
#endif
#endif
#undef CONVERT_16_FWD

View File

@@ -360,6 +360,7 @@ typedef struct AudioBootStrap
const char *desc;
bool (*init)(SDL_AudioDriverImpl *impl);
bool demand_only; // if true: request explicitly, or it won't be available.
bool is_preferred;
} AudioBootStrap;
// Not all of these are available in a given build. Use #ifdefs, etc.

View File

@@ -1775,6 +1775,7 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
int result;
Uint32 chunkcount = 0;
Uint32 chunkcountlimit = 10000;
const Sint64 flen = SDL_GetIOSize(src); // this might be -1 if the IOStream can't determine the total size.
const char *hint;
Sint64 RIFFstart, RIFFend, lastchunkpos;
bool RIFFlengthknown = false;
@@ -1883,6 +1884,14 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
fmtchunk = *chunk;
}
} else if (chunk->fourcc == DATA) {
/* If the data chunk is bigger than the file, it might be corrupt
or the file is truncated. Try to recover by clamping the file
size. This also means a malicious file can't allocate 4 gigabytes
for the chunks without actually supplying a 4 gigabyte file. */
if ((flen > 0) && ((chunk->position + chunk->length) > flen)) {
chunk->length = (Uint32) (flen - chunk->position);
}
/* Only use the first data chunk. Handling the wavl list madness
* may require a different approach.
*/
@@ -2114,8 +2123,8 @@ bool SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8
result = WaveLoad(src, &file, spec, audio_buf, audio_len);
if (!result) {
SDL_free(*audio_buf);
audio_buf = NULL;
audio_len = 0;
*audio_buf = NULL;
*audio_len = 0;
}
// Cleanup

View File

@@ -309,6 +309,12 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
ctx.AAudioStreamBuilder_setSampleRate(builder, device->spec.freq);
ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels);
// If no specific buffer size has been requested, the device will pick the optimal
if(SDL_GetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES)) {
ctx.AAudioStreamBuilder_setBufferCapacityInFrames(builder, 2 * device->sample_frames); // AAudio requires that the buffer capacity is at least
ctx.AAudioStreamBuilder_setFramesPerDataCallback(builder, device->sample_frames); // twice the size of the data callback buffer size
}
const aaudio_direction_t direction = (recording ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT);
ctx.AAudioStreamBuilder_setDirection(builder, direction);
ctx.AAudioStreamBuilder_setErrorCallback(builder, AAUDIO_errorCallback, device);
@@ -366,7 +372,7 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
hidden->processed_bytes = 0;
hidden->callback_bytes = 0;
hidden->semaphore = SDL_CreateSemaphore(recording ? 0 : hidden->num_buffers);
hidden->semaphore = SDL_CreateSemaphore(recording ? 0 : hidden->num_buffers - 1);
if (!hidden->semaphore) {
LOGI("SDL Failed SDL_CreateSemaphore %s recording:%d", SDL_GetError(), recording);
return false;
@@ -545,7 +551,7 @@ static bool AAUDIO_Init(SDL_AudioDriverImpl *impl)
}
AudioBootStrap AAUDIO_bootstrap = {
"AAudio", "AAudio audio driver", AAUDIO_Init, false
"AAudio", "AAudio audio driver", AAUDIO_Init, false, false
};
#endif // SDL_AUDIO_DRIVER_AAUDIO

View File

@@ -31,7 +31,7 @@ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuild
SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aaudio_format_t format))
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode))
SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
SDL_PROC(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) // API 28
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) // API 28

View File

@@ -566,7 +566,7 @@ static enum snd_pcm_chmap_position sdl_channel_maps[SDL_AUDIO_ALSA__SDL_CHMAPS_N
};
// Helper for the function right below.
static bool has_pos(unsigned int *chmap, unsigned int pos)
static bool has_pos(const unsigned int *chmap, unsigned int pos)
{
for (unsigned int chan_idx = 0; ; chan_idx++) {
if (chan_idx == 6) {
@@ -586,7 +586,7 @@ static bool has_pos(unsigned int *chmap, unsigned int pos)
#define HAVE_REAR 1
#define HAVE_SIDE 2
#define HAVE_BOTH 3
static void sdl_6chans_set_rear_or_side_channels_from_alsa_6chans(unsigned int *sdl_6chans, unsigned int *alsa_6chans)
static void sdl_6chans_set_rear_or_side_channels_from_alsa_6chans(unsigned int *sdl_6chans, const unsigned int *alsa_6chans)
{
// For alsa channel maps with 6 channels and with SND_CHMAP_FL,SND_CHMAP_FR,SND_CHMAP_FC,
// SND_CHMAP_LFE, reduce our 6 channels maps to a uniq one.
@@ -638,7 +638,7 @@ static void sdl_6chans_set_rear_or_side_channels_from_alsa_6chans(unsigned int *
#undef HAVE_SIDE
#undef HAVE_BOTH
static void swizzle_map_compute_alsa_subscan(struct ALSA_pcm_cfg_ctx *ctx, int *swizzle_map, unsigned int sdl_pos_idx)
static void swizzle_map_compute_alsa_subscan(const struct ALSA_pcm_cfg_ctx *ctx, int *swizzle_map, unsigned int sdl_pos_idx)
{
swizzle_map[sdl_pos_idx] = -1;
for (unsigned int alsa_pos_idx = 0; ; alsa_pos_idx++) {
@@ -652,7 +652,7 @@ static void swizzle_map_compute_alsa_subscan(struct ALSA_pcm_cfg_ctx *ctx, int *
}
// XXX: this must stay playback/recording symetric.
static void swizzle_map_compute(struct ALSA_pcm_cfg_ctx *ctx, int *swizzle_map, bool *needs_swizzle)
static void swizzle_map_compute(const struct ALSA_pcm_cfg_ctx *ctx, int *swizzle_map, bool *needs_swizzle)
{
*needs_swizzle = false;
for (unsigned int sdl_pos_idx = 0; sdl_pos_idx != ctx->chans_n; sdl_pos_idx++) {
@@ -668,7 +668,7 @@ static void swizzle_map_compute(struct ALSA_pcm_cfg_ctx *ctx, int *swizzle_map,
#define CHMAP_NOT_FOUND 2
// Should always be a queried alsa channel map unless the queried alsa channel map was of type VAR,
// namely we can program the channel positions directly from the SDL channel map.
static int alsa_chmap_install(struct ALSA_pcm_cfg_ctx *ctx, unsigned int *chmap)
static int alsa_chmap_install(struct ALSA_pcm_cfg_ctx *ctx, const unsigned int *chmap)
{
bool isstack;
snd_pcm_chmap_t *chmap_to_install = (snd_pcm_chmap_t*)SDL_small_alloc(unsigned int, 1 + ctx->chans_n, &isstack);
@@ -698,7 +698,7 @@ static int alsa_chmap_install(struct ALSA_pcm_cfg_ctx *ctx, unsigned int *chmap)
// We restrict the alsa channel maps because in the unordered matches we do only simple accounting.
// In the end, this will handle mostly alsa channel maps with more than one SND_CHMAP_NA position fillers.
static bool alsa_chmap_has_duplicate_position(struct ALSA_pcm_cfg_ctx *ctx, unsigned int *pos)
static bool alsa_chmap_has_duplicate_position(const struct ALSA_pcm_cfg_ctx *ctx, const unsigned int *pos)
{
if (ctx->chans_n < 2) {// we need at least 2 positions
LOGDEBUG("channel map:no duplicate");
@@ -1156,7 +1156,7 @@ static bool ALSA_OpenDevice(SDL_AudioDevice *device)
#if SDL_ALSA_DEBUG
snd_pcm_uframes_t bufsize;
ALSA_snd_pcm_hw_params_get_buffer_size(cfg_ctx.hwparams, &bufsize);
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO,
"ALSA: period size = %ld, periods = %u, buffer size = %lu",
cfg_ctx.persize, cfg_ctx.periods, bufsize);
#endif
@@ -1187,7 +1187,6 @@ static bool ALSA_OpenDevice(SDL_AudioDevice *device)
ALSA_snd_pcm_nonblock(cfg_ctx.device->hidden->pcm, 0);
}
#endif
ALSA_snd_pcm_start(cfg_ctx.device->hidden->pcm);
return true; // We're ready to rock and roll. :-)
err_cleanup_ctx:
@@ -1200,6 +1199,13 @@ err_free_device_hidden:
return false;
}
static void ALSA_ThreadInit(SDL_AudioDevice *device)
{
SDL_SetCurrentThreadPriority(device->recording ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL);
// do snd_pcm_start as close to the first time we PlayDevice as possible to prevent an underrun at startup.
ALSA_snd_pcm_start(device->hidden->pcm);
}
static ALSA_Device *hotplug_devices = NULL;
static int hotplug_device_process(snd_ctl_t *ctl, snd_ctl_card_info_t *ctl_card_info, int dev_idx,
@@ -1497,6 +1503,7 @@ static bool ALSA_Init(SDL_AudioDriverImpl *impl)
impl->DetectDevices = ALSA_DetectDevices;
impl->OpenDevice = ALSA_OpenDevice;
impl->ThreadInit = ALSA_ThreadInit;
impl->WaitDevice = ALSA_WaitDevice;
impl->GetDeviceBuf = ALSA_GetDeviceBuf;
impl->PlayDevice = ALSA_PlayDevice;
@@ -1513,7 +1520,7 @@ static bool ALSA_Init(SDL_AudioDriverImpl *impl)
}
AudioBootStrap ALSA_bootstrap = {
"alsa", "ALSA PCM audio", ALSA_Init, false
"alsa", "ALSA PCM audio", ALSA_Init, false, false
};
#endif // SDL_AUDIO_DRIVER_ALSA

View File

@@ -420,7 +420,8 @@ static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_pl
hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY);
if (hint) {
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) {
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0 ||
SDL_strcasecmp(hint, "ambient") == 0) {
category = AVAudioSessionCategoryAmbient;
} else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) {
category = AVAudioSessionCategorySoloAmbient;
@@ -1034,7 +1035,7 @@ static bool COREAUDIO_Init(SDL_AudioDriverImpl *impl)
}
AudioBootStrap COREAUDIO_bootstrap = {
"coreaudio", "CoreAudio", COREAUDIO_Init, false
"coreaudio", "CoreAudio", COREAUDIO_Init, false, false
};
#endif // SDL_AUDIO_DRIVER_COREAUDIO

View File

@@ -206,7 +206,7 @@ static void DSOUND_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDe
{
#ifdef HAVE_MMDEVICEAPI_H
if (SupportsIMMDevice) {
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording);
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording, SDL_AUDIO_UNKNOWN);
} else
#endif
{
@@ -674,7 +674,7 @@ static bool DSOUND_Init(SDL_AudioDriverImpl *impl)
}
AudioBootStrap DSOUND_bootstrap = {
"directsound", "DirectSound", DSOUND_Init, false
"directsound", "DirectSound", DSOUND_Init, false, false
};
#endif // SDL_AUDIO_DRIVER_DSOUND

View File

@@ -165,7 +165,7 @@ static bool DISKAUDIO_Init(SDL_AudioDriverImpl *impl)
}
AudioBootStrap DISKAUDIO_bootstrap = {
"disk", "direct-to-disk audio", DISKAUDIO_Init, true
"disk", "direct-to-disk audio", DISKAUDIO_Init, true, false
};
#endif // SDL_AUDIO_DRIVER_DISK

View File

@@ -297,7 +297,7 @@ static bool DSP_Init(SDL_AudioDriverImpl *impl)
}
AudioBootStrap DSP_bootstrap = {
"dsp", "Open Sound System (/dev/dsp)", DSP_Init, false
"dsp", "Open Sound System (/dev/dsp)", DSP_Init, false, false
};
#endif // SDL_AUDIO_DRIVER_OSS

View File

@@ -131,5 +131,5 @@ static bool DUMMYAUDIO_Init(SDL_AudioDriverImpl *impl)
}
AudioBootStrap DUMMYAUDIO_bootstrap = {
"dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, true
"dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, true, false
};

Some files were not shown because too many files have changed in this diff Show More