In some cases, such as when recreating a window during renderer initialization, a failure can leave the window in a state where the internal structure has already been freed, but the higher level window object needs to be destroyed separately. Check that the internal handle is valid before attempting to access any data during destruction.
Allows for graceful failure instead of a crash during cleanup if renderer creation fails.
Use doubles and apply an offset to account for rounding errors due to Wayland scale increments being in units of 1/120. This fixes the backbuffer size calculations with certain combinations of size/scale values, and future-proofs the Wayland backend, as 32-bit floats become increasingly error-prone with larger dimensions and/or scale factors.
The conversion formula is now point->pixel->point round trip safe as well.
This used a tiny stack, which apparently upsets Blender for various
technical reasons. Instead, just use the default stack size, which should
give it plenty of space to work.
If the thread failed to create, we would then wait on a semaphore that would
never trigger, so don't do that anymore!
Fixes#10806.
GameInput currently has a bug with keys stuck on focus change, and crashes on initialization on some systems, so we'll disable it until these issues are fixed.
@smcv may have found the root cause of the pipewire thread crash, so removing the pipewire client version check to re-enable use of pipewire in older container runtimes.
hotplug_loop_init() calls pw_context_new(), which creates a thread
internally (for the "data loop"). It also creates a thread of its own,
the `hotplug_loop`.
Both of these threads are running code from libpipewire, so before we
can allow the Pipewire library to be unloaded, we need to destroy
the context with pw_context_destroy() and destroy the `hotplug_loop`
with pw_thread_loop_destroy().
Resolves: https://github.com/libsdl-org/SDL/issues/10787
Signed-off-by: Simon McVittie <smcv@collabora.com>
On most Unix platforms supported by SDL, the canonical name used to load
a library at runtime includes its ABI major version, and the name
without a version is not guaranteed to exist on non-developer systems.
libX11-xcb.so.1 is correct on Linux, and probably on other Unix
platforms like FreeBSD.
A notable exception is OpenBSD, which apparently does not use
ABI-suffixed names, so continue to use libX11-xcb.so there.
Signed-off-by: Simon McVittie <smcv@collabora.com>
When debugging crash reports, it's helpful to know which thread is
associated with which external library.
Linux limits the length of a thread name to 15 bytes (not including the
zero-termination), so abbreviate Pipewire to "pw" and hotplug to "plug"
to fit the desired information into the allowed space.
Signed-off-by: Simon McVittie <smcv@collabora.com>
We make sure we initialize XInput first, so that anything checking whether it's enabled gets a valid result based on whether we were able to load it or not.
- CreateEventEx() is guarded by _WIN32_WINNT >= 0x0600:
In SDL_gpu_d3d12.c, include core/windows/SDL_windows.h
that defines _WIN32_WINNT properly to account for that
- DXGIInfoQueue stuff is not available in all toolchains
such as mingw-w64 version 8.0.3
- SDL_gpu_d3d11.c: _WIN32 is always defined by MinGW, as
is the case for all windows-targeting compilers, so it
doesn't guarantee absence of DXGIInfoQueue stuff:
rely on __IDXGIInfoQueue_INTERFACE_DEFINED__, as it is
done elsewhere.
Fixes: https://github.com/libsdl-org/SDL/issues/10705 .
Allow setting a parent/child relationship on toplevel windows, which allows raising sets of windows together, and allows child windows to always float above their parents.
Modal windows are now set by setting the parent, then toggling modal status, as the previous interface duplicated functionality now handled by SDL_SetWindowParent().
The default value of MAX_FRAMES_IN_FLIGHT (3) may be less than the
minImageCount returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() on
some setups. For example, the Intel IVB Vulkan driver on Wayland returns
a minImageCount of 4, resulting in the following validation warning:
VUID-VkSwapchainCreateInfoKHR-presentMode-02839(ERROR / SPEC): msgNum: -76493605 - Validation Error: [ VUID-VkSwapchainCreateInfoKHR-presentMode-02839 ] | MessageID = 0xfb70ccdb | vkCreateSwapchainKHR(): pCreateInfo->minImageCount 3, which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. minImageCount = 4, maxImageCount = 0). The Vulkan spec states: If presentMode is not VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR nor VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, then minImageCount must be greater than or equal to the value returned in the minImageCount member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkSwapchainCreateInfoKHR-presentMode-02839)
Objects: 0
Use the minimum image count in that case, as it's as close as we'll get
to our preferred value. Note also that, unlike maxImageCount,
minImageCount is never 0 (the spec states it is always at least 1), so
we don't need a similar check to see if it applies.
Signed-off-by: David Gow <david@ingeniumdigital.com>
The `colorAttachmentDescriptions` field of `SDL_GPUGraphicsPipelineAttachmentInfo` should be marked `const`,
similarly to the `vertexBindings` and `vertexAttributes` fields of `SDL_GPUVertexInputState`.
Using the @() syntax to construct an NSString assumes the parenthesized
pointer is null-terminated, but the Metal shader source included in
render/sdlgpu/shaders/metal.h is not null-terminated.
Quoting the clang documentation on Objective-C literals:
When the type of the parenthesized expression is (char *) or (const
char *), the result of the boxed expression is a pointer to an
NSString object containing equivalent character data, which is
assumed to be ‘\0’-terminated and UTF-8 encoded.
Because the @() syntax assumes null-termination, it may read garbage
data after the shader source (up to the next null byte), which can then
cause the Metal shader compiler to fail. To prevent this, instead of
using the @() boxing syntax, we explicitly construct an NSString using
the string length passed by the caller.
These functions had special cases for a few BC formats, but all
block-compressed formats should need the same logic. Furthermore they
weren't handling the sRGB variants of those formats.
OutputDebugString and fprintf(stderr) (of mslibc) both output
to the debug window of Visual Studio.
In other debuggers (e.g. RAD), this does not happen.
To avoid double output, this commit always uses WriteFile/WriteConsole.
Most SDL functions used to indicate success or failure using an int return code. These functions have been changed to return SDL_bool.
Here is a coccinelle patch to change code that previously compared the return value to 0 and changes it to a boolean test:
@ bool_return_type @
identifier func =~ "^(SDL_AddEventWatch|SDL_AddHintCallback|SDL_AddSurfaceAlternateImage|SDL_AddVulkanRenderSemaphores|SDL_BindAudioStream|SDL_BindAudioStreams|SDL_BlitSurface|SDL_BlitSurface9Grid|SDL_BlitSurfaceScaled|SDL_BlitSurfaceTiled|SDL_BlitSurfaceTiledWithScale|SDL_BlitSurfaceUnchecked|SDL_BlitSurfaceUncheckedScaled|SDL_CaptureMouse|SDL_ClearAudioStream|SDL_ClearClipboardData|SDL_ClearComposition|SDL_ClearError|SDL_ClearProperty|SDL_ClearSurface|SDL_CloseIO|SDL_CloseStorage|SDL_ConvertAudioSamples|SDL_ConvertEventToRenderCoordinates|SDL_ConvertPixels|SDL_ConvertPixelsAndColorspace|SDL_CopyFile|SDL_CopyProperties|SDL_CopyStorageFile|SDL_CreateDirectory|SDL_CreateStorageDirectory|SDL_CreateWindowAndRenderer|SDL_DateTimeToTime|SDL_DestroyWindowSurface|SDL_DetachVirtualJoystick|SDL_DisableScreenSaver|SDL_EnableScreenSaver|SDL_EnumerateDirectory|SDL_EnumerateProperties|SDL_EnumerateStorageDirectory|SDL_FillSurfaceRect|SDL_FillSurfaceRects|SDL_FlashWindow|SDL_FlipSurface|SDL_FlushAudioStream|SDL_FlushRenderer|SDL_GL_DestroyContext|SDL_GL_GetAttribute|SDL_GL_GetSwapInterval|SDL_GL_LoadLibrary|SDL_GL_MakeCurrent|SDL_GL_SetAttribute|SDL_GL_SetSwapInterval|SDL_GL_SwapWindow|SDL_GetAudioDeviceFormat|SDL_GetAudioStreamFormat|SDL_GetCameraFormat|SDL_GetClosestFullscreenDisplayMode|SDL_GetCurrentRenderOutputSize|SDL_GetCurrentTime|SDL_GetDXGIOutputInfo|SDL_GetDateTimeLocalePreferences|SDL_GetDisplayBounds|SDL_GetDisplayUsableBounds|SDL_GetGDKDefaultUser|SDL_GetGDKTaskQueue|SDL_GetGamepadSensorData|SDL_GetGamepadTouchpadFinger|SDL_GetHapticEffectStatus|SDL_GetJoystickBall|SDL_GetMasksForPixelFormat|SDL_GetPathInfo|SDL_GetRectUnion|SDL_GetRectUnionFloat|SDL_GetRenderClipRect|SDL_GetRenderColorScale|SDL_GetRenderDrawBlendMode|SDL_GetRenderDrawColor|SDL_GetRenderDrawColorFloat|SDL_GetRenderLogicalPresentation|SDL_GetRenderLogicalPresentationRect|SDL_GetRenderOutputSize|SDL_GetRenderSafeArea|SDL_GetRenderScale|SDL_GetRenderVSync|SDL_GetRenderViewport|SDL_GetSensorData|SDL_GetStorageFileSize|SDL_GetStoragePathInfo|SDL_GetSurfaceAlphaMod|SDL_GetSurfaceBlendMode|SDL_GetSurfaceClipRect|SDL_GetSurfaceColorKey|SDL_GetSurfaceColorMod|SDL_GetTextInputArea|SDL_GetTextureAlphaMod|SDL_GetTextureAlphaModFloat|SDL_GetTextureBlendMode|SDL_GetTextureColorMod|SDL_GetTextureColorModFloat|SDL_GetTextureScaleMode|SDL_GetTextureSize|SDL_GetWindowAspectRatio|SDL_GetWindowBordersSize|SDL_GetWindowMaximumSize|SDL_GetWindowMinimumSize|SDL_GetWindowPosition|SDL_GetWindowRelativeMouseMode|SDL_GetWindowSafeArea|SDL_GetWindowSize|SDL_GetWindowSizeInPixels|SDL_GetWindowSurfaceVSync|SDL_HideCursor|SDL_HideWindow|SDL_Init|SDL_InitHapticRumble|SDL_InitSubSystem|SDL_LoadWAV|SDL_LoadWAV_IO|SDL_LockAudioStream|SDL_LockProperties|SDL_LockSurface|SDL_LockTexture|SDL_LockTextureToSurface|SDL_MaximizeWindow|SDL_MinimizeWindow|SDL_MixAudio|SDL_OpenURL|SDL_OutOfMemory|SDL_PauseAudioDevice|SDL_PauseAudioStreamDevice|SDL_PauseHaptic|SDL_PlayHapticRumble|SDL_PremultiplyAlpha|SDL_PremultiplySurfaceAlpha|SDL_PushEvent|SDL_PutAudioStreamData|SDL_RaiseWindow|SDL_ReadStorageFile|SDL_ReadSurfacePixel|SDL_ReadSurfacePixelFloat|SDL_RegisterApp|SDL_ReloadGamepadMappings|SDL_RemovePath|SDL_RemoveStoragePath|SDL_RemoveTimer|SDL_RenamePath|SDL_RenameStoragePath|SDL_RenderClear|SDL_RenderCoordinatesFromWindow|SDL_RenderCoordinatesToWindow|SDL_RenderFillRect|SDL_RenderFillRects|SDL_RenderGeometry|SDL_RenderGeometryRaw|SDL_RenderLine|SDL_RenderLines|SDL_RenderPoint|SDL_RenderPoints|SDL_RenderPresent|SDL_RenderRect|SDL_RenderRects|SDL_RenderTexture|SDL_RenderTexture9Grid|SDL_RenderTextureRotated|SDL_RenderTextureTiled|SDL_RequestAndroidPermission|SDL_RestoreWindow|SDL_ResumeAudioDevice|SDL_ResumeAudioStreamDevice|SDL_ResumeHaptic|SDL_RumbleGamepad|SDL_RumbleGamepadTriggers|SDL_RumbleJoystick|SDL_RumbleJoystickTriggers|SDL_RunHapticEffect|SDL_SaveBMP|SDL_SaveBMP_IO|SDL_SendAndroidMessage|SDL_SendGamepadEffect|SDL_SendJoystickEffect|SDL_SendJoystickVirtualSensorData|SDL_SetAppMetadata|SDL_SetAppMetadataProperty|SDL_SetAudioDeviceGain|SDL_SetAudioPostmixCallback|SDL_SetAudioStreamFormat|SDL_SetAudioStreamFrequencyRatio|SDL_SetAudioStreamGain|SDL_SetAudioStreamGetCallback|SDL_SetAudioStreamInputChannelMap|SDL_SetAudioStreamOutputChannelMap|SDL_SetAudioStreamPutCallback|SDL_SetBooleanProperty|SDL_SetClipboardData|SDL_SetClipboardText|SDL_SetCursor|SDL_SetFloatProperty|SDL_SetGamepadLED|SDL_SetGamepadMapping|SDL_SetGamepadPlayerIndex|SDL_SetGamepadSensorEnabled|SDL_SetHapticAutocenter|SDL_SetHapticGain|SDL_SetJoystickLED|SDL_SetJoystickPlayerIndex|SDL_SetJoystickVirtualAxis|SDL_SetJoystickVirtualBall|SDL_SetJoystickVirtualButton|SDL_SetJoystickVirtualHat|SDL_SetJoystickVirtualTouchpad|SDL_SetLinuxThreadPriority|SDL_SetLinuxThreadPriorityAndPolicy|SDL_SetLogPriorityPrefix|SDL_SetMemoryFunctions|SDL_SetNumberProperty|SDL_SetPaletteColors|SDL_SetPointerProperty|SDL_SetPointerPropertyWithCleanup|SDL_SetPrimarySelectionText|SDL_SetRenderClipRect|SDL_SetRenderColorScale|SDL_SetRenderDrawBlendMode|SDL_SetRenderDrawColor|SDL_SetRenderDrawColorFloat|SDL_SetRenderLogicalPresentation|SDL_SetRenderScale|SDL_SetRenderTarget|SDL_SetRenderVSync|SDL_SetRenderViewport|SDL_SetScancodeName|SDL_SetStringProperty|SDL_SetSurfaceAlphaMod|SDL_SetSurfaceBlendMode|SDL_SetSurfaceColorKey|SDL_SetSurfaceColorMod|SDL_SetSurfaceColorspace|SDL_SetSurfacePalette|SDL_SetSurfaceRLE|SDL_SetTLS|SDL_SetTextInputArea|SDL_SetTextureAlphaMod|SDL_SetTextureAlphaModFloat|SDL_SetTextureBlendMode|SDL_SetTextureColorMod|SDL_SetTextureColorModFloat|SDL_SetTextureScaleMode|SDL_SetThreadPriority|SDL_SetWindowAlwaysOnTop|SDL_SetWindowAspectRatio|SDL_SetWindowBordered|SDL_SetWindowFocusable|SDL_SetWindowFullscreen|SDL_SetWindowFullscreenMode|SDL_SetWindowHitTest|SDL_SetWindowIcon|SDL_SetWindowKeyboardGrab|SDL_SetWindowMaximumSize|SDL_SetWindowMinimumSize|SDL_SetWindowModalFor|SDL_SetWindowMouseGrab|SDL_SetWindowMouseRect|SDL_SetWindowOpacity|SDL_SetWindowPosition|SDL_SetWindowRelativeMouseMode|SDL_SetWindowResizable|SDL_SetWindowShape|SDL_SetWindowSize|SDL_SetWindowSurfaceVSync|SDL_SetWindowTitle|SDL_SetiOSAnimationCallback|SDL_ShowAndroidToast|SDL_ShowCursor|SDL_ShowMessageBox|SDL_ShowSimpleMessageBox|SDL_ShowWindow|SDL_ShowWindowSystemMenu|SDL_StartTextInput|SDL_StartTextInputWithProperties|SDL_StopHapticEffect|SDL_StopHapticEffects|SDL_StopHapticRumble|SDL_StopTextInput|SDL_SyncWindow|SDL_TimeToDateTime|SDL_TryLockMutex|SDL_TryLockRWLockForReading|SDL_TryLockRWLockForWriting|SDL_TryWaitSemaphore|SDL_UnlockAudioStream|SDL_UpdateHapticEffect|SDL_UpdateNVTexture|SDL_UpdateTexture|SDL_UpdateWindowSurface|SDL_UpdateWindowSurfaceRects|SDL_UpdateYUVTexture|SDL_Vulkan_CreateSurface|SDL_Vulkan_LoadLibrary|SDL_WaitConditionTimeout|SDL_WaitSemaphoreTimeout|SDL_WarpMouseGlobal|SDL_WriteStorageFile|SDL_WriteSurfacePixel|SDL_WriteSurfacePixelFloat)$";
@@
(
func(
...
)
- == 0
|
- func(
+ !func(
...
)
- < 0
|
- func(
+ !func(
...
)
- != 0
|
- func(
+ !func(
...
)
- == -1
)
On Emscripten without pthreads, this would fail because SDL can't spin the
audio device thread, and the dummy backend didn't manage a thread itself.
With this patch, we use setInterval to fire the usual audio thread iterators
between iterations of the Emscripten mainloop on the main thread.
Fixes#10573.
This was causing crashes in IGameInput_RegisterSystemButtonCallback(), presumably on older systems with runtimes using a different function signature. We'll just disable it for now until the GameInput runtime has stabilized and we can tell when it's safe to use.
This is undocumented since the individual flags are separate window creation properties, but it's useful to have a shared definition for this, which is used internally and for migrating code from SDL2.
src/video/wayland/SDL_waylanddatamanager.c
Log data + primary_selection _offer_receive
src/video/wayland/SDL_waylandevents.c + SDL_waylanddatamanager.h
Log data + primary_selection events
Split FILE vs TEXT events : booleans has_mime_ text + file
Handle text/plain;charset=utf-8 data offer
This changes the API in various ways, and updates the backends for this.
Overall, this is a massive simplification of the API, as most future backends
can't support the previously-offered API.
This also removes the testautomation pen code (not only did these interfaces
change completely, it also did something no other test did: mock the internal
API), and replaces testpen.c with a different implementation (the existing
code was fine, it was just easier to start from scratch than update it).
This is now being done at a higher level, so we don't want to duplicate it here.
Fixes the mouse cursor staying hidden if you enable relative mode, alt-tab away and then alt-tab back.
Require more than one warp to the window center within a certain timespan (currently 30ms, but can be tweaked) to better avoid erroneously entering warp emulation mode.
This also correctly resets the warp emulation mode activation if the window loses and regains focus.
When debugging a GUI application in Visual Studio,
text printed with fprintf(stderr) will also be sent to the debug stream.
When buiding SDL with SDL_LIBC=ON, this patch makes logging skip
OutputDebugString and rely on fprintf(stderr) to send the text to
the debugger.
If there are bugs it's possible that the window pointer is invalid. Double check it before sending the application events and potentially dereferencing it.
This showed up in https://github.com/libsdl-org/SDL/issues/10494 as a window getting mouse focus as it was being destroyed and then crashing later when mouse focus was set to a different window.
This adds functions to query the keymap:
* SDL_GetCurrentKeymap()
* SDL_GetKeymapKeycode()
* SDL_GetKeymapScancode()
* SDL_ReleaseKeymap()
and these are distinct from the function to query the event keycode associated with a scancode, which might be affected by SDL_HINT_KEYCODE_OPTIONS.
Also added an SDL_bool parameter to SDL_GetKeyName() and SDL_GetKeyFromName() to enable upper case handling of the name.
It turns out that the non-Latin keyboards (Russian, Thai, Greek, etc.) are almost all QWERTY layout plus native language labels. Feedback from users is that they expect to see the ASCII keycodes and key names when using those keyboards, so we'll enable this option by default.
Using the shifted versions of keys for the key names doesn't make any sense on the Thai keyboard. Thai keyboards are QWERTY plus Thai characters, so let's use the ASCII key names.
SDL_Keycode is defined as the unshifted key on the keyboard, but the key name is defined as the letter printed on that key, which is usually the shifted capital letter.
Fixes https://github.com/libsdl-org/SDL/issues/5836
SDL_Log() no longer prints a log prefix by default for SDL_LOG_PRIORITY_INFO and below. The log prefixes can be customized with SDL_SetLogPriorityPrefix().
This makes the subsystem thread-safe, more performant, and cleans up the code a little.
Also removed SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, since setting this hint programmatically initializes properties, which creates a lock, so we can't check hints while creating locks. The slim reader-writer locks have been the default for ages and are solid, so we'll just use those when available.
Allow multiple bootstrap entries for a single video driver with the same name, which internally allows preferential and fallback init conditions while hiding the implementation details from applications (e.g. applications will just see "wayland", regardless of whether it's using the preferred or fallback driver list entry).
If a driver is requested, all instances of it in the list will be tried before reporting failure, and client applications programmatically enumerating the video drivers will be presented with a deduplicated list of entries.
Wayland has a myriad of unresolved problems regarding surface suspension
blocking forever in QueuePresent/SwapBuffers when occludedand the FIFO
(vsync) implementation being fundamentally broken leading to reduced
GPU-bound performance and 'barcoding' frametimes due to swapchain
starvation.
There are two protocols used to solve these two problems together --
fifo-v1 and commit-timing-v1, which implement the commit queue on the
compositor side, and a timestamp that frames are intended to be
displayed for/discarded respectfully.
To avoid severe performance regressions for developers targeting SDL3,
only pick Wayland as the default backend when these two protocols are
supported -- otherwise fallback to X11/XWayland.
We do this by having two VideoBootStraps, one which is tests the
preferred case, "wayland_preferred" (ie. if fifo-v1 + commit-timing-v1
are available init time), and the fallback, which is just "wayland",
the same name as before, which does no such tests.
Thus, forcing with SDL_VIDEO_DRIVER=wayland will go onto the fallback
option, and pick Wayland always, as usual, so there is no behaviour
change.
In the case that X11/XWayland is not available (ie. no DISPLAY), we will
still fallback to using Wayland without these protocols available.
Signed-off-by: Joshua Ashton <joshua@froggi.es>
Support SDL_EVENT_DROP_TEXT in Windows
src/video/windows/SDL_windowsvideo.c + .h
Connect to COM WIN_CoInitialize + OLE OleInitialize in WIN_VideoInit
Disconnect from COM WIN_CoUninitialize + OLE OleUninitialize in WIN_VideoQuit
src/video/windows/SDL_windowswindow.c + .h
Create / Destroy IDropTarget or use fallback WM_DROPFILES
depending on OleInitialize success in WIN_VideoInit
Handle text/uri-list, text/plain;charset=utf-8, CF_UNICODE_TEXT, CF_TEXT, CF_HDROP
Call terminating WIN_AcceptDragAndDrop from WIN_DestroyWindow ( CleanupVideoData )
We want to keep mouse timestamps consistently using the same interval, and it's helpful to know when multiple keyboard events come in at the same time.
This avoids lots of build issues with the various D3D12 headers out there (MinGW, old Windows SDKs, etc) and also opens the door for WSL2 libd3d12.so support.
Note that the build system has not been changed; technically _all_ platforms now have d3d12.h but we should only enable the backend when it's actually expected to work.
It's possible to get message times out of order when processing the Windows message queue, so this passes those times through unchanged, while still detecting when the message tick wraps.
This patch fixes two issues with pausing and resuming the Android
activity when an external graphics context[1] is used:
1. When pausing, don't wait for the EGL context to be backed up if a
context wasn't created in the first place.
2. When resuming, don't recreate the EGL surface unless one was
requested by the user when originally creating the window.
[1] SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN
When the native window or surface backing the SDL window changes, e.g.,
when the activity is resumed, we should also update the corresponding
window pointer properties (SDL_PROP_WINDOW_ANDROID_{WINDOW,SURFACE}
_POINTER) so that they remain in sync.
This prevents continuing a rumble after the first one fails, and fixes a long standing crash issue if rumble is started immediately before the controller is disconnected.
Thanks to @AntTheAlchemist for the key bug report that showed what was happening here.
Fixes https://github.com/libsdl-org/SDL/issues/10422
The AAudio driver implemented pause/resume by dangerously locking the audio devices. If there was an audio hotplug event or a background thread tried to interact with the audio system, this could cause deadlocks.
0500b30c550900001472000001000000 is the ID when the controller is connected via Bluetooth and 0300b30c550900001472000011010000 is for USB mode.
Tested by setting "SDL_GAMECONTROLLERCONFIG" in some games.
Removed duplicate hints SDL_HINT_APP_NAME, SDL_HINT_APP_ID, and
SDL_HINT_AUDIO_DEVICE_APP_NAME.
Wired up a few things to use the metadata; more to come!
Fixes https://github.com/libsdl-org/SDL/issues/4703
If someone calls SDL_Quit(), then runs an SDL function that implicitly initializes TLS or logging, and then calls SDL_Quit() again, we want to make sure we run through the quit process again. Each of the Init/Quit calls are protected against being called multiple times.
The supported texture formats were leaking. In order to catch future issues, we'll just do a full teardown of the renderer in the failure case, and make sure it's safe to do so with a partially initialized renderer.
It was intended to make the API easier to use, but various automatic garbage collection all had flaws, and making the application periodically clean up temporary memory added cognitive load to using the API, and in many cases was it was difficult to restructure threaded code to handle this.
So, we're largely going back to the original system, where the API returns allocated results and you free them.
In addition, to solve the problems we originally wanted temporary memory for:
* Short strings with a finite count, like device names, get stored in a per-thread string pool.
* Events continue to use temporary memory internally, which is cleaned up on the next event processing cycle.
Whoever provided the window has already set it up the way they want it.
Fixes SDL removing iconified or maximized state when creating a window from an existing OS window.
Move the Wayland pointer warp emulation code up to the SDL mouse layer, and activate it when a client attempts to warp a hidden mouse cursor when the hint is set.
testrelative adds the ability to test the warp emulation activation/deactivation with the --warp parameter and 'c' key for toggling cursor visibility.
When the phone is in portrait mode and the window is in landscape mode, the view changes orientation after layoutSubviews runs. In this case we need some way of notifying the application that the Metal view has changed.
On iOS, the application gets one last change to process messages before going into the background. We do the same on Android, which more closely matches the previous behavior.
This change also decouples the pause/resume handling from the video subsystem on Android, so applications that don't use SDL for video can get application life cycle events.
The semantics for the life cycle events are that they need to be handled in an event watch callback, and once they've been delivered, the application will block until it's been resumed. SDL_HINT_ANDROID_BLOCK_ON_PAUSE can be used to control that behavior, and if that's set to "0", then the application will continue to run in the background at low CPU usage until being resumed or stopped.
SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO has been removed, and the audio will be paused when the application is paused.
Fixes https://github.com/libsdl-org/SDL/issues/3193
This makes it more clear that these events can't be handled in the normal event loop. It also makes pause and resume transparent to applications that don't handle them, which is a nice side effect.
Cursor visibility in the SDL input layer only reflects whether ShowCursor/HideCursor was called. In the case of relative mode, the cursor can be hidden, but the SDL_Mouse visibility flag will be true.
Track cursor visibility separately in the X11 driver. Fixes the cursor becoming visible when using the warping relative mode with XWayland.
This was just causing confusion and anxiety. SDL temporary memory will be automatically freed on the main thread when processing events and on other threads when it ages out after a second. The application can free it directly by calling SDL_ClaimTemporaryMemory() to get ownership of the pointer, if necessary.
We're limiting the functions to rects with positions and sizes < 1 billion for speed, which is totally fine for most SDL use cases. If you need rectangles larger than that, you can roll your own functions that use 64-bit intermediate values and do proper overflow handling of output values.
Fixes https://github.com/libsdl-org/SDL/issues/8879
src/video/cocoa/SDL_cocoawindow.m
Support Copy in addition to Generic as Drag and Drop operation,
Register and Support public.utf8-plain-text for SDL_EVENT_DROP_TEXT.
* A floating point rectangle contains all points >= x and <= x + w
* A floating point rectangle is only empty if it has negative width. The zero rectangle contains the zero point.
* Adjacent floating point rectangles intersect along their shared side
Fixes https://github.com/libsdl-org/SDL/issues/6791
SDL_BlitSurfaceScaled() is more flexible and uses the SDL_SoftStretch() fast path when possible. Having two surface scaling APIs was confusing, especially when one of them has unexpected limitations.
This was originally to avoid duplicating clipping work in Maelstrom on a 486 computer. This has been confusing for users and computers are a little faster these days, so we'll make it work the way people expect.
This allows threads to free memory from their local pool without affecting events that are queued, and to transfer memory ownership cleanly between threads that are queuing and dequeuing events.
Always use the size sent by the compositor when transitioning back to the floating state on the xdg-toplevel path, unless the client explicitly requested a new floating size while the window was in a fixed-size state.
If a window is requested to be maximized or made fullscreen while an uncommitted size request is pending, the surface will first be committed so that the compositor will set the new size when the window is restored.
Fixes the window being wrongly resized when leaving the maximized state in KDE.
This restores the behaviour before 9221548114 where we only preventDefault the event if:
- the key is recognised
- the event is enabled
- the event is not filtered
(ignoring the KEYPRESS special case, which is unchanged)
(cherry picked from commit 6e931bee01)
This more closely matches the mental model of people using SDL, and locking a surface that isn't RLE encoded doesn't cause any issues.
Fixes https://github.com/libsdl-org/SDL/issues/5594
The function can now convert between pixels of different formats, and takes a parameter to control whether the premultiplication is done in sRGB or linear space.
Also added SDL_PremultiplySurfaceAlpha(), which can premultiply the pixels of a surface in-place.
Applying these changes to external code doesn't actually improve anything, and within the context of the other Get* functions for renderers and surfaces, these stand out as outliers, so I'm going to back this change out.
Fixes a type redefinition error:
In file included from /tmp/SDL3/test/../src/events/SDL_events_c.h:28,
from /tmp/SDL3/test/../src/events/SDL_pen.c:26,
from /tmp/SDL3/test/testautomation_pen.c:83:
/tmp/SDL3/test/../src/events/../video/SDL_sysvideo.h:34: error: redefinition of typedef 'SDL_DisplayModeData'
/tmp/SDL3/include/SDL3/SDL_video.h:78: note: previous declaration of 'SDL_DisplayModeData' was here
This was done to SDL_DisplayMode for consistency with SDL_Surface and gives it a type so we don't have to do casts in SDL code.
I considered switching to an ID and hashing the driver data, etc. but all of that involved a lot of internal code churn and this solution gives us flexibility in how we handle this in the future.
After consideration, I made this renaming global across the project, for consistency.
Fixes https://github.com/libsdl-org/SDL/issues/10198
It also now caches at the higher level, so the platform-specific bits don't
change their interface much.
A little code hygiene work was applied to some of the platform bits on top of
this.
Reference Issue #10229.
This provides a highly accurate sleep function for your application, although you are still subject to being switched out occasionally.
Fixes https://github.com/libsdl-org/SDL/issues/10210
While it makes sense to get an object pointer from an object ID, you want to get object attributes for an ID, otherwise e.g. GetNameFromID() sounds like it's a name ID, not an object ID. This is also consistent with the function naming convention in SDL2.
Without unlocking, we trigger an assertion failure in SDL_sysmutex.c at line 80 (i.e. 'rc == 0'). Each lock-unlock pair should ideally cancel each other out, maintaining a reference count that returns to zero.
Previously, the Wayland backend did not implement support for this hint and always passed focus clicks through. Obey the hint to match the behavior of other platforms.
The preferred Pipewire path requires both devices being available, and that a sufficiently recent underlying core version is running on the host system. These criteria were being checked separately, which required two separate instances of enumerating the Pipewire registry, which is a fairly heavy operation. Move the version info callback to the main hotplug thread to avoid enumerating the registry twice, and check for both the version and required devices at the same time on the preferred path.
Currently, all SDL_Surfaces with an indexed pixel format have an
associated SDL_Palette. This palette either consists of entirely the
colour black, or -- in the special case of 1-bit surfaces, black and
white.
When an indexed surface is blitted to another indexed surface, a 'map'
is generated from the source surface's palette to the destination
surfaces palette, in order to preserve the look of the image if the
palettes differ.
However, in most cases, applications will want to blit the raw index
values, rather than translate to make the colours as similar as
possible. For instance, the destination surface's palette may have been
modified to fade the screen out.
This change allows an indexed surface to have no associated palette. If
either the source or destination surface of a blit do not have a
palette, then the raw indices are copied (assuming both have an indexed
format).
This mimics better what happens with most other APIs (such as
DirectDraw), where most users do not set a palette on any surface but
the screen, whose palette is implicitly used for the whole application.
Turns out that there isn't a strong OpenGL naming convention for "Delete" ...
WGL offers "wglDeleteContext" but the GLX equivalent is "glxDestroyContext"
and then EGL sealed the deal by going with Destroy as well! Since it matches
SDL3 naming conventions (Create/Destroy), we're renaming it.
Fixes#10197.
The SDL_Surface rework in #10201 adds some extra checks that the pixel
format enum matches the SDL_PixelFormatDetails struct, which is largely
filled in with values from SDL_GetMasksForPixelFormat().
However, there are a few cases where these do not match:
- Indexed 1-, 2-, and 4-bit formats encode a bytes_per_pixel of 0, but
SDL_GetMasksForPixelFormat() gives a value of 1.
- Packed formats, like SDL_PIXELFORMAT_XRGB8888 encode a bits_per_pixel
of the number of used bits (24), but SDL_GetMasksForPixelFormat()
includes the padding byte, giving a total of 32.
We could change the encoding of these in the enum, or change what we store
in the details struct to match, but I suspect we'd either break something
that relies on it, or lose some (_maybe_ useful) information. In the meantime,
this gets the tests working again.
Signed-off-by: David Gow <david@ingeniumdigital.com>
SDL_Surface has been simplified and internal details are no longer in the public structure.
The `format` member of SDL_Surface is now an enumerated pixel format value. You can get the full details of the pixel format by calling `SDL_GetPixelFormatDetails(surface->format)`. You can get the palette associated with the surface by calling SDL_GetSurfacePalette(). You can get the clip rectangle by calling SDL_GetSurfaceClipRect().
SDL_PixelFormat has been renamed SDL_PixelFormatDetails and just describes the pixel format, it does not include a palette for indexed pixel types.
SDL_PixelFormatEnum has been renamed SDL_PixelFormat and is used instead of Uint32 for API functions that refer to pixel format by enumerated value.
SDL_MapRGB(), SDL_MapRGBA(), SDL_GetRGB(), and SDL_GetRGBA() take an optional palette parameter for indexed color lookups.
Setting the window geometry on the xdg-toplevel path is a hack used to prevent protocol violations if a buffer with an old size is committed. Since viewports decouple the window geometry from the buffer size, this is not needed if viewports are supported.
Fixes an invalid window geometry warning and incorrect window overview size for fullscreen windows in GNOME.
This reverts commit 3c90b1c1f6.
It turns out this is problematic for sdl2-compat. We're investigating a more complete separation between SDL2 and SDL3 surfaces, but in the meantime, I'll fix the breakage.
This commit fixes the attribute list in the WGL and GLX code when requesting a floating point pixel format. The name of the attribute was missing in the list.
Fixes libsdl-org#10189
Add a loop around SDL_hid_read() in the Steam Deck HIDAPI driver as it
is done in other HIDAPI drivers. This loop reads data from the device and
processes it until the input buffer is empty which ensures that clients
always get the latest data.
This fixes an input latency issue if the application polls the events
slower than the hardware generates them.
This reverts commit 9f8dffbd2d.
This causes some tests to fail, and wasn't otherwise a necessary change, so
I'm backing it out.
(Looks like some sort of interaction with software renderers and their
surfaces not getting destroyed...?)
Any parameters (key/value pairs after the '?' in a URL) that have a keyname
that starts with `SDL_` will be put into Emscripten's environment variable
emulation table at startup, before SDL_main runs.
This lets users set hints the same way they might set them from a shell's
command line on a desktop platform:
For example:
`https://example.com/my_sdl3_application.html?SDL_RENDER_DRIVER=software`
Fixes#10154.
This was added by the Unreal Engine to handle the input focus for popups and dialogs, window types for which SDL3 has built-in, cross-platform support.
This was only ever implemented in X11, and the only purpose was to hint that a client application may want to call the SDL_SetWindowInputFocus() function, which has since been removed, rendering it pointless now.
This was added to SDL2 for the Unreal Engine's implementation of menus and dialogs on X11, window types for which SDL3 has added built-in, cross-platform support.
Remove this function, as it was only ever implemented for X11 and is now basically useless aside from allowing annoying or malicious client apps to discretely steal focus. As the documentation states: "You almost certainly want SDL_RaiseWindow() instead of this function."
This allows the numpad to work as the user expects based on the numlock state. If the application needs to distinguish the keys, it can check to see whether the scancode is a numpad key or not.
XInput2 will grab the pointer on button presses, which causes the grab attempt to fail and ultimately timeout since the pointer is already grabbed, however, ungrabbing the pointer when no buttons are pressed and the pointer is outside the window can generate enter/leave notify events, which result in further calls of the grab function. The end result is an infinite loop of grab/ungrab attempts generating enter/leave events. This causes a hang in testautomation when creating a window with the grabbed flag if the pointer is not positioned within window bounds.
Check the button state and only ungrab if a mouse button is in the pressed state.
After discussion with @ocornut, SDL_RenderGeometryRaw() will take floating point colors and conversion from 8-bit color can happen on the application side. We can always add an 8-bit color fast path in the future if we need it on handheld platforms.
If you need code to do this in your application, you can use the following:
int SDL_RenderGeometryRaw8BitColor(SDL_Renderer *renderer, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, int num_vertices, const void *indices, int num_indices, int size_indices)
{
int i, retval, isstack;
const Uint8 *color2 = (const Uint8 *)color;
SDL_FColor *color3;
if (num_vertices <= 0) {
return SDL_InvalidParamError("num_vertices");
}
if (!color) {
return SDL_InvalidParamError("color");
}
color3 = (SDL_FColor *)SDL_small_alloc(SDL_FColor, num_vertices, &isstack);
if (!color3) {
return -1;
}
for (i = 0; i < num_vertices; ++i) {
color3[i].r = color->r / 255.0f;
color3[i].g = color->g / 255.0f;
color3[i].b = color->b / 255.0f;
color3[i].a = color->a / 255.0f;
color2 += color_stride;
color = (const SDL_Color *)color2;
}
retval = SDL_RenderGeometryRaw(renderer, texture, xy, xy_stride, color3, sizeof(*color3), uv, uv_stride, num_vertices, indices, num_indices, size_indices);
SDL_small_free(color3, isstack);
return retval;
}
Fixes https://github.com/libsdl-org/SDL/issues/9009
The new function includes the cursor position so IME UI elements can be placed relative to the cursor, as well as having the whole text area available so on-screen keyboards can avoid it.
If window transparency was requested via the SDL_WINDOW_TRANSPARENT flag, don't set the opaque bit on the swapchain composite alpha value. Fixes transparent windows when using the Vulkan renderer (e.g. testsprite --transparent).
(This means "new value" and returns the atomically updated value. Before, we
were returning a value from a void function.)
(cherry picked from commit 498cbffd89)
Steam ran into a crash SDL_XINPUT_JoystickDetect() with XINPUTGETCAPABILITIES being NULL. I'm not sure how that happened, and there may still be a race condition if this is a multi-threaded issue, but at least this is more correct.
* Don't need to initialize values already zeroed
* Added debug message logging
* Don't send duplicate SDL_EVENT_TEXT_EDITING events with empty text
* Send the length of selected text in the SDL_EVENT_TEXT_EDITING event
* Fixed potential crashes when out of memory
This fixes corrupt framebuffers on platforms that require the use of modifiers.
(cherry picked from commit 620e875335)
(cherry picked from commit 6589287ed6)
KeymapNotify events happen on focus events, as well as when the keymap group changes. Query the current group and don't rebuild the keymap if it hasn't changed.
Note that some IME changes, such as activating intelligent Japanese or Chinese input methods on Gnome, will only trigger IBus activation, and won't send a keymap or group update as they use the existing layout.
SDL_StartTextInput(), SDL_StopTextInput(), SDL_TextInputActive(), SDL_ClearComposition(), and SDL_SetTextInputRect() all now take a window parameter.
This change also fixes IME candidate positioning when SDL_SetTextInputRect() is called before SDL_StartTextInput(), as is recommended in the documentation.
Switching between layouts with the same group number (e.g. US to Japanese) were incorrectly filtered out with this change, as it doesn't trigger a MappingNotify event.
This reverts commit 3d42412650.
KeymapNotify events happen on focus events, as well as when the key group changes. Query the current group and don't rebuild the keymap if it hasn't changed.
XkbKeycodeToKeySym is replaced with XkbLookupKeySym, which can take the modifier states. The associated cmake check has been renamed for consistency.
Only the XKB path is currently handled. The deprecated XKeycodeToKeysym path is TODO.
Normally this would be done by creating a PQ swap chain and a linear SRGB render target and doing blending operations in linear space and then final conversion to PQ HDR, but we're going to short-circuit all of that and just support linear SRGB output directly.
Proton uses this on Linux to determine what the XInput slot is for the gamepad. Other applications will get the real controller name and VID/PID by virtue of the code in SDL_steam_virtual_gamepad.c
I _did_ appreciate the explanation, but it doesn't have to live in the
source code; also we can just release `devuid` and then check for error with
the usual macro, since SDL is done with it either way at this point.
A minimized window may not be associated with any displays, so check that the output array is valid and that there is at least one associated display before dereferencing.
Fixes a crash when attempting to unset fullscreen on a minimized window.
For GTK-based systems using XSETTINGS it's much more likely to be
available, rather than the "GDK_SCALE" environment variable, which is a
debugging tool according to the GTK documentation.
Import the XSettingsClient implementation to handle the settings
selection.
Currently, we only care about the Gdk/WindowScalingFactor value used by
the windowing system to notify us of display-wide changes in the scaling
factor.
If XInput2 is enabled, it will grab the pointer on button presses, which results in XGrabPointer returning AlreadyGrabbed. Clear any existing grabs before attempting the confinement grab to avoid a timeout scenario.
These are integer values internally, but the API has been changed to make it easier to mix other render code with querying those values.
Fixes https://github.com/libsdl-org/SDL/issues/7519
Testing:
* Run test/testwm
* Hit Ctrl-R to toggle relative mode
* Alt-tab away
* Move the mouse over testwm
* Note that the cursor is visible until testwm gains focus
This fixes numerous problems regarding dead keys on Wayland. Most notably, Wayland was enforcing dead keys on SDL_KEYDOWN and SDL_KEYUP events, which caused unresponsiveness on keys that were mapped to dead keys (tilde on US-Intl is most notable for this, commonly used as a console key).
When starting text input, not all state was reset properly. The text input protocol requires to be re-enabled every time text input changes, which SDL did not do. Also, XKB compose state was not reset at all, causing composite and dead keys to carry over from when text input was disabled.
Manual cherry-pick of 1c3090a1ac by Hanicef
My phone captured 1920x1080 images even though the highest reported format was higher resolution, so I adjusted testcamera to be able to handle different sized images than expected.
Fixes https://github.com/libsdl-org/SDL/issues/9930
It's possible to destroy an SDL_Renderer without freeing it using
SDL_DestroyRendererWithoutFreeing(), which is used to make it possible
to destroy windows and their renderers in either order. However, if a
renderer has already been destroyed before it is freed (e.g., the window
was destroyed before the renderer), the object is never marked invalid.
This means the SDL_Renderer is reported as leaked, even if
SDL_DestroyRenderer() is called.
SDL_GetWindowSurface() will trigger this, as the window texture is
cleaned up _after_ the window destroys its associated renderer. This
makes it impossible to use SDL_FRAMEBUFFER_ACCELERATION without
triggering a leak warning.
Fix this by unconditionally marking the SDL_Renderer object as invalid
in SDL_DestroyRenderer().
This declares that any `const char *` returned from SDL is owned by SDL, and
promises to be valid _at least_ until the next time the event queue runs, or
SDL_Quit() is called, even if the thing that owns the string gets destroyed
or changed before then.
This is noted in the headers as "the SDL_GetStringRule", so this will both be
greppable to find a detailed explaination in docs/README-strings.md and
wikiheaders will automatically turn it into a link we can point at the
appropriate documentation.
Fixes#9902.
(and several FIXMEs, both known and yet-undocumented.)
Borderless windows flagged as fullscreen at creation time turn on the borders, because doing so prevents some window managers from wrongly positioning the borderless window, and in these cases the borders need to be removed whether fullscreen is exited programmatically or via a compositor event. Set a flag when forcing the borders on, so they will be removed in all cases later.
/tmp/SDL3/src/video/windows/SDL_windowswindow.c: In function 'WIN_SetWindowPositionInternal':
/tmp/SDL3/src/video/windows/SDL_windowswindow.c:216:17: warning: 'h' may be used uninitialized in this function [-Wmaybe-uninitialized]
rect.bottom = *height;
~~~~~~~~~~~~^~~~~~~~~
/tmp/SDL3/src/video/windows/SDL_windowswindow.c:320:12: note: 'h' was declared here
int w, h;
^
/tmp/SDL3/src/video/windows/SDL_windowswindow.c:215:16: warning: 'w' may be used uninitialized in this function [-Wmaybe-uninitialized]
rect.right = *width;
~~~~~~~~~~~^~~~~~~~
/tmp/SDL3/src/video/windows/SDL_windowswindow.c:320:9: note: 'w' was declared here
int w, h;
^
This reverts commit 2de2e9d031.
The fullscreen state is no longer available to check, and the actual bug this was trying to work around was fixed in ad813a65e7
Note that Wayland places a restriction on windows being resized, where the requested size passed to the configuration event is a maximum, and attempting to exceed it is a protocol violation, so trying to grow the window by dragging the sides only vertically or horizontally is limited, as the provided dimensions can't be exceeded.
In practice, nothing seems to kill clients that do this, but the more immediate problem is that doing so causes GNOME to glitch out.
We're seeing people with legit PipeWire installs that don't export any
devices, that are also running a (not emulated) PulseAudio install that
works.
This solution might still get tweaked some more, but it seems to be working
so far.
The HDR properties are zeroed and set in WIN_GetHDRProperties, and using the struct without calling this function results in sending uninitialized data.
In file included from /tmp/SDL3/src/events/SDL_events_c.h:28,
from /tmp/SDL3/src/SDL.c:46:
/tmp/SDL3/src/events/../video/SDL_sysvideo.h:31: error: redefinition of typedef 'SDL_VideoDevice'
/tmp/SDL3/src/video/SDL_video_c.h:27: note: previous declaration of 'SDL_VideoDevice' was here
The wp_alpha_modifier_v1 protocol allows for a global blending factor to be specified for an entire surface. Use this to add support for SDL_SetWindowOpacity().
In some cases, size data set programmatically could be overwritten by old configuration data, particularly when on the display scaling path. This refactors the configuration code to be much more strict and verbose regarding the handling of window sizes, which fixes some scenarios where tests were failing when display scaling was activated.
Video backends that run asynchronously can wind up in a race situation if a mode or position update request queues up a fullscreen enter request while an unprocessed asynchronous leave request is in flight, and the mode switch or position update request is processed after the leave request, causing the window to erroneously return to fullscreen.
Instead of the internal SDL_UpdateFullscreenMode and backend SetWindowFullscreen functions taking a boolean value, use an enum that allows the backends to distinguish between "this is an explicit fullscreen enter/leave request", and "this is an update request to change the mode or position". Communicating the specific intent allows the backend to early-out when required, which prevents windows from erroneously returning to fullscreen due to update requests made after a leave request, and allows for the removal of some internal synchronization previously needed to (attempt to) work around this, which improves overall performance while also increasing robustness.
This is only relevant to the internal functions, and nothing in the public-facing API has been changed.
In some cases, the fullscreen deadline handler can be hit before the associated configure event is received, resulting in the constraints being erroneously restored. The state is doubled buffered, so it shouldn't interfere with the pending fullscreen dimensions, but it isn't correct behavior.
According to the spec, calls to set/unset fullscreen will always have an associated configure event, and the constraints will be reapplied as needed there.
Non-size configuration events are filtered out, so there is no need to enqueue an event when setting the size, as it won't be overwritten in the configure event when only changing state.
Otherwise, this will crash if the app sets its own SDL_malloc allocator, since
SDL_iconv uses SDL_malloc.
WideCharToMultibyte lets us calculate the needed memory for the argv[] string
conversions, and then we use the win32 HeapAlloc() API to get some memory
for it.
Fixes#8967.
If a window is fullscreen and the maximized state is requested, it needs to be explicitly entered after leaving fullscreen, or the resulting window will be in the maximized state, but still the size of the non-maximized window.
In include/SDL3/SDL_test_common.h
Add flag hide_cursor
In src/test/SDL_test_common.c
Handle option --hide-cursor to SDL_HideCursor
Handle Ctrl-h toggle to SDL_HideCursor and SDL_ShowCursor
It was only used if SSE wasn't supported (available since the Pentium III in
1999), or the data was aligned to 8 bytes but not aligned to 16 bytes.
The likelihood of ever hitting this codepath seems extremely low.
The spec says that an undefined confinement region should match the input region, so it is resized automatically.
This was a hack for a very old, buggy compositor and is no longer needed.
At best, it simply doesn't work, and if it does, it frequently warps the pointer to the wrong position as the window animates in/out of fullscreen mode.
It can also inadvertently trigger the relative warp mode emulation mode on Wayland if a fullscreen transition occurs while the client has the pointer hidden.
During playback, don't queue another buffer unless there are none in the queue.
During capture, there may be multiple buffers of audio available.
WASAPI_CaptureFromDevice only processes one buffer, and if we always wait on the next event, we will never catch up if it falls behind.
Added SDL_Vulkan_DestroySurface, its documentation and corresponding platform specific implementations. Fixed some header inclusion orders to improve consistency between platforms. Added TODOs regarding MetalView creation and destruction which will benefit from the new functionality.
This extends the display scaling mode to be global and work in terms of pixels everywhere, with the content scale value set on displays. The per-window property had some issues, and has been removed in favor of retaining only the global hint that changes all coordinates to pixel values, sets the content scale on the displays, and generally makes the Wayland backend behave similarly to Win32 or X11.
Some additional work was needed to fix cases where displays can appear to overlap, since Wayland desktops are always described in logical coordinates, and attempting to adjust the display positions so that they don't overlap can get very ugly in all but the simplest cases, as large gaps between displays can result.
The flags parameter has been removed from SDL_CreateRenderer() and SDL_RENDERER_PRESENTVSYNC has been replaced with SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER during window creation and SDL_PROP_RENDERER_VSYNC_NUMBER after renderer creation.
SDL_SetRenderVSync() now takes additional values besides 0 and 1.
The maximum texture size has been removed from SDL_RendererInfo, replaced with SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER.
This breaks applications using them in DirectInput mode, which isn't worth just getting battery status. We'll turn on enhanced mode if the application enables sensors.
Noticed this in SDL-1.2 where gcc-13 emits a -Wuse-after-free warning.
No such warning in SDL2 and SDL3, because unlike SDL1.2, SDL_realloc()
is not a macro expanding to libc realloc(). It warns, of course, if
SDL_realloc() is replaced with plain realloc():
src/stdlib/SDL_iconv.c: In function 'SDL_iconv_string_REAL':
src/stdlib/SDL_iconv.c:824:39: warning: pointer 'oldstring' may be used after 'realloc' [-Wuse-after-free]
824 | outbuf = string + (outbuf - oldstring);
| ~~~~~~~~^~~~~~~~~~~~
src/stdlib/SDL_iconv.c:818:30: note: call to 'realloc' here
818 | string = (char *)realloc(string, stringsize + sizeof(Uint32));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noticed this in SDL-1.2 in a gcc-13 build, which emitted the following
warning: (No such warnings in SDL2 and SDL3, due to macro differences)
./src/video/x11/SDL_x11sym.h:84:48: warning: argument 2 of type 'char *' declared as a pointer [-Warray-parameter=]
84 | SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return)
| ~~~~~~^
./src/video/x11/SDL_x11dyn.c:95:15: note: in definition of macro 'SDL_X11_SYM'
95 | rc fn params { ret p##fn args ; }
| ^~~~~~
In file included from ./src/video/x11/SDL_x11dyn.h:27,
from ./src/video/x11/SDL_x11dyn.c:26:
/usr/include/X11/Xlib.h:2980:5: note: previously declared as an array 'char[32]'
2980 | char [32] /* keys_return */
| ^~~~~~~~~
The original actually was char[32] but was changed with
8ada1e8a6e
(https://bugzilla.libsdl.org/show_bug.cgi?id=170https://github.com/libsdl-org/SDL-1.2/issues/101)
The shorthand version of this function didn't allow specifying a controller name, which seems pretty important. It seems like anyone actually implementing a virtual joystick is going to want to use some of the extended functionality.
Remove the custom server version check. We can easily do this as part of
starting the hotplug loop. Check that we are at least running against a
1.0.0 server.
Log the compiled, linked, server and required versions.
Check that we are compiled and linked with the right version before using
the time symbol of a struct.
The PipeWire camera will enumerate the pipewire Video/Source nodes with
their formats.
When capturing is started, a stream to the node will be created and
frames will be captured.
This allows applications to re-query the values if the system locale is changed during runtime, and better matches the other locale functions. A note is included in the documentation mentioning that this can be slow, as it has to call into OS functions.
Also allows for the removal of the init/quit time functions, as they are no longer needed.
Queries the "panel orientation" property on the connector and reports it in degrees of clockwise rotation via the 'SDL.display.KMSDRM.panel_orientation' display property.
This is provided by the kernel as a hint to userspace applications, and the application itself is ultimately responsible for any required coordinate transformations needed to conform to the requested orientation.
This will provide a quick and easy way of clearing the error when a function succeeds, if we want to do that in a more widespread way.
For now we guarantee that SDL_Init() will never have an error set when it returns successfully.
Fixes https://github.com/libsdl-org/SDL/issues/8421
The pointer confinement protocol does allow attempted warping the pointer via a hint, provided that the pointer is locked at the time of the request, and the requested coordinates fall within the bounds of the window.
Toggle the pointer locked state and request the pointer warp when the required protocol is available. This is similar to what XWayland does internally.
- Adds support for modal windows to Win32, Mac, and Haiku, and enhances functionality on Wayland and X11, which previous set only the parent window, but not the modal state.
- Windows can be declared modal at creation time, and the modal state can be toggled at any time via SDL_SetWindowModalFor() (tested with UE5 through sdl2-compat).
- Allows dynamic unparenting/reparenting of windows.
- Includes a modal window test.
This fixes a bunch of issues with dialogs on Windows.
- Removed lpstrFileTitle assignation, which overwrote the buffer
- Increased the memory size available for long file selections
- Removed seemingly unused `default_folder` in win_Args struct
- Properly handle the case where only one file is selected in multiselect mode
- Properly handle the initial folder, which would fail in specific conditions
The details for the last entry are explained in a comment in the code.
LINUX_JoystickInit does a manual scan first so devices are sorted.
If SDL_UDEV_Init hasn't run by then, then the product info cannot
be looked up by SDL_UDEV_GetProductInfo and the initial-plugged-
in-device classification falls back to heuristic guessing.
(cherry picked from commit 0963c11af8)
Closing a device file takes 0.01 to 0.5s, which can add up to
significant startup delays. The udev classification does not
require opening the actual device files, so, use it if possible,
and only fall back to opening the device and probing otherwise.
(cherry picked from commit 45b804c158)
Some backends, such as Wayland, don't support explicit mouse capture, and thus don't implement the backend function to do so, but do set/unset the capture flag on button events to handle cases where a button is pressed and the pointer is dragged outside the window.
If the backend doesn't support explicitly setting the mouse capture mode, manually clear the capture flag when the window has had the focus forcibly removed, to avoid sending bogus motion events as well as an assert condition.
Trying to capture the pointer via XGrabPointer() when XInput2 is in use will always fail with 'AlreadyGrabbed', since the pointer is already grabbed by XInput2.
- A refactor changed how SetupWindowData handled external windows where previously it was tracked
in a field of SDL_CocoaWindowData but now it is tracked by setting SDL_WINDOW_EXTERNAL in the
window flags. Removed the now unused field and updated the external window check in DestroyWindow.
The "jump magic" codepath was never written, and would have involved a lot
of low-level and platform/processor/compiler specific work.
A better solution is for compilers to treat the function call in the jump
table functions as a tail call, which would effectively produce the same
result in a portable way.
Clang already has a way to do this that we could add later. But this wouldn't
need a separate "jump magic" section.
This was hardcoded to disabled, since building it in bloated the binary
massively for little gain (one could probably accomplish this same thing
with ltrace or something).
If we need it, we'll pull it out of revision control.
This allows apps to destroy the window and renderer in either order, but
makes sure that the renderer can properly clean up its resources while OpenGL
contexts and libraries are still loaded, etc.
If the window is destroyed first, the renderer is (mostly) destroyed but its
pointer remains valid. Attempts to use the renderer will return an error,
but it can still be explicitly destroyed, at which time the struct is free'd.
If the renderer is destroyed first, everything works as before, and a new
renderer can still be created on the existing window.
Fixes#9540.
Previously, each backend would allocate and free the renderer struct. Now
the higher level does it, so the backends only manage their private resources.
This removes some boilerplate and avoids some potential accidents.
Headless display servers might not send an initial configure event, so don't assume that one has arrived and send garbage size/position values when showing a window.
Otherwise, it isn't immediately clear to the client application as to why its windows suddenly disappeared, and it received a quit event out of nowhere.
When running in a container, the underlying Pipewire version may not match the library version, so retrieve and check the core version info to see if it meets the preferred version requirements.
Checking for the pipewire-pulse service is unreliable when used in containers such as Flatpak, so simply use a minimum version check instead and prefer it over the Pulseaudio backend if at least version 1.0.0.
XWayland emulates the XRandR interface, so it still needs the actual mode switch call to trigger the mode switching emulation.
There is also no need to wait when using XWayland mode switching emulation, as it is handled via viewport scaling and thus instantaneous.
Otherwise, when you call SDL_CreateCondition() in something that can otherwise
survive in a single-threaded build, you'll get an error that seems fatal.
We already do this for mutexes and rwlocks (but not semaphores!)
Fixes#9558.
This allows using a much smaller (1.5 KB) lookup table, in exchange for a small amount of extra work per frame.
The extra work (a few extra loads/mul/adds) is negligible, and can execute in parallel.
The reduction in cache misses almost certainly outweighs any added cost.
The table is generated at runtime, and takes less than 0.02ms on my computer.
Compiler support for loading/storing multiple registers at once (i.e vld1q_f32_x4) seems very poor, so avoiding them for now.
Also switched to aligned stores with SSE. Although both SSE and NEON support unaligned stores, there is more likely to be a penalty to them, i.e when crossing a cache line. So might as align them.
XWayland seems to require that the pointer be hidden when it is warped, so hide and show the pointer when warping, if required.
Note that XWayland still only allows warping within the window, so attempts to warp to global coordinates outside the window won't work.
This could happen if `enabled` was non-zero but not set to SDL_TRUE.
Static analysis tried to warn us!!
The added SDL_assert is meant to sanity check this, not pacify the analyzer;
this passes Clang's static analysis now, with or without the assert.
Fixes#9544.
That way we don't do the awful minimise on focus loss logic by default on XWayland where mode switching is emulated (like on the Wayland backend).
This fixes CS2, Dota 2 minimising on alt-tab when playing in fullscreen (which is really annoying when managing eg. Discord on another screen)
Some window managers can send garbage values during the initial mapping of a window, and need the position set again after mapping to ensure proper placement. Position requests sent before mapping can otherwise end up ignored. Ignore initial configure events when initially showing the window, and make sure that the position is set after the window is mapped, either when the window borders appear, or after the initial configure events in the case of borderless windows.
This also eliminates sending excessive/redundant move requests, which can cause strange behavior on some window managers, particularly if done before the window is actually mapped.
Fixes cases of incorrect initial window placement on GNOME + XWayland.
Fullscreen windows may be larger than the display if they were moved between differently sized displays and the new position was received before the new size or vice versa. Using the center of the window rect in this case can report the wrong display, so use the origin.
Fixes flickering and the window bouncing between different displays when moving fullscreen X11 and Wayland windows in certain multi-monitor layouts.
When moving a fullscreen window, the compositor movement animation can cause it to cross multiple displays, sending multiple display changed events, which can cause the window to jitter or be snapped to the wrong display in the case of exclusive fullscreen modes.
When moving fullscreen windows, only send the display changed event when the window isn't on multiple displays to avoid spurious display changed events.
If we need to extend this in the future, we'll make a second struct and
a second SDL_AttachVirtualJoystickEx-style function that uses it.
Just zero the struct and don't set a version.
Fixes#9489.
Connector names prior to v4 were sent via xdg-output, so use that if an older version of libwayland is present.
Additionally, ensure the output names are actually allocated before comparing the strings.
Use DBus to query Systemd to check if the pipewire-pulse service is in the "running" state. If it is, then it is certain that Pipewire is being used instead of Pulseaudio as the preferred system mixer.
If DBus support is not enabled or Systemd is not being used on the underlying system, this check will simply fail and the standard driver order will be tested.
This is just stuff I noticed while working on the wikiheaders updates. A
thorough pass over all the docs would not be terrible, and maybe a simple
script to check for consistency (does everything have a `\since` on it? etc)
might be nice, too.
- Add a globally-accessible function to handle the parsing of filter extensions
- Remove the ability of putting the wildcard ('*') among other patterns; it's either a list of patterns or a single '*' now
- Add a hint to select between portals and Zenity on Unix
Using the current window size at the time of the call may not be correct if the window or buffer size was changed after the fact, so always set the damage region to cover the entire buffer.
For whatever reason, `ExtractIconEx` returns icons whose sizes are
inappropriate for the current DPI, resulting in terribly-blurry
window icons at higher DPIs.
To solve this, the window icon is now set to the first icon group
that is present in the executable. This behaviour should match what
Explorer does. By selecting an icon group instead of a specific icon,
Windows is free to select the icon within the group that best suits
the current DPI.
(cherry picked from commit 1fa6142903)
Otherwise, they might find out strings with malformed UTF-8 sequences produce
a different amount of codepoints than the count returned here, overflowing
buffers that might be allocated based on the results.
This fixes an macOS bug that is only known to occur in fullscreen windows on the built-in displays of newer MacBooks with camera notches. When the mouse is moved near the top of such a window (within about 44 units) and then moved back down, the cursor rects aren't respected. This can cause the default cursor to be visible when it should not be.
(cherry picked from commit f1690e265e)
GetSystemTimePreciseAsFileTime is only available on Win8/Server 2012 or higher, so it must be dynamically loaded and only used if available. Fixes compatability with Win7 and XP.
SDL_strcasecmp (even when calling into a C runtime) does not work with
Unicode chars, and depending on the user's locale, might not work with
even basic ASCII strings.
This implements the function from scratch, using "case-folding,"
which is a more robust method that deals with various languages. It
involves a hashtable of a few hundred codepoints that are "uppercase" and
how to map them to lowercase equivalents (possibly increasing the size of
the string in the process). The vast majority of human languages (and
Unicode) do not have letters with different cases, but still, this static
table takes about 10 kilobytes on a 64-bit machine.
Even this will fail in one known case: the Turkish 'i' folds differently
if you're writing in Turkish vs other languages. Generally this is seen as
unfortunate collateral damage in cases where you can't specify the language
in use.
In addition to case-folding the codepoints, the new functions also know how
to decode the various formats to turn them into codepoints in the first
place, instead of blindly stepping by one byte (or one wchar_t) per
character.
Also included is casefolding.txt from the Unicode Consortium and a perl
script to generate the hashtable from that text file, so we can trivially
update this if new languages are added in the future.
A simple test using the new function:
```c
#include <SDL3/SDL.h>
int main(void)
{
const char *a = "α ε η";
const char *b = "Α Ε Η";
SDL_Log(" strcasecmp(\"%s\", \"%s\") == %d\n", a, b, strcasecmp(a, b));
SDL_Log("SDL_strcasecmp(\"%s\", \"%s\") == %d\n", a, b, SDL_strcasecmp(a, b));
return 0;
}
```
Produces:
```
INFO: strcasecmp("α ε η", "Α Ε Η") == 32
INFO: SDL_strcasecmp("α ε η", "Α Ε Η") == 0
```
glibc strcasecmp() fails to compare a Greek lowercase string to its uppercase
equivalent, even with a UTF-8 locale, but SDL_strcasecmp() works.
Other SDL_stdinc.h functions are changed to be more consistent, which is to
say they now ignore any C runtime and often dictate that only English-based
low-ASCII works with them.
Fixes Issue #9313.
This was previous behavior that used window userdata and was lost during the move to properties. Renderer objects need to be cleaned up when their associated windows are destroyed, or they can be leaked and backend refcounts won't be properly updated, leading to them not being properly shut down when SDL_Quit() is called.
The dimensions for fixed-size state set via window flags will be applied later in the window creation process.
Restores the window to the proper windowed size when leaving fullscreen.
I believe there was a O(n^2) device walking issues on startup
- MaybeAddDevice gets called for every device at startup
- MaybeAddDevice calls IsJoystick
- IsJoystick calls SDL_UDEV_GetProductInfo
- SDL_UDEV_GetProductInfo calls udev_enumerate_scan_devices
- udev_enumerate_scan_devices walks all the devices
Prior to commit 3b1e0e1 this was mostly masked as IsJoystick only
called SDL_UDEV_GetProductInfo when a JSIOCGNAME ioctl was
successful. This fixes the O(n^2) behaviour by directly getting
the device via udev_device_new_from_devnum (based on type, major,
and minor number) instead of enumerating everything via
udev_enumerate_scan_devices and matching on name.
- Fixes a leak in pen name allocation that would trigger
for both X11 and Wayland for some non-pen input devices
when new devices are added/removed.
- SDL_PenQuit() now deallocates and resets the table of known pens
- testautomation_pen.c now uses PenInit and PenQuit as setup and
teardown, respectively
testautomation_pen.c was already triggering the leak, and it is
visible with --trackmem, so no new tests are added.
Send keyboard and mouse added/removed events when seat capabilities change. Note that Wayland only supports one global keyboard and mouse object per seat, so events coming from different keyboards and mice on the same seat can't be distinguished.
If we get ENOENT we call that success. If the parent directory doesn't exist, that's fine, other operations on it will fail if it matters to the application.
Some POSIX platforms don't define macros to note the presence of the POSIX.1-2008 st_*tim timespec members of the stat struct, so check if this member exists during CMake configuration and conditionally enable it.
Apple platforms use st_*timespec naming, which is supported as of OSX 10.6. SDL3 requires 10.9+, so no fallback is needed.
Android only supports the POSIX.1-2008 semantics as of API version 26 or higher, so this has to be conditionally enabled in the makefile build via an API version definition check.
In other cases, file times fall back to the legacy path with second precision.
Adds functions to query the system's realtime clock, convert time intervals to/from a calendar date and time in either UTC or the local time, and perform time related calculations.
An SDL_Time type (a time interval represented in nanoseconds), and SDL_DateTime struct (broken down calendar date and time) were added to facilitate this functionality.
Querying the system time results in a value expressed in nanoseconds since the Unix epoch (Jan 1, 1970) in UTC +0000. Conversions to and from the various platform epochs and units are performed when required.
Any direct handling of timezones and DST were intentionally avoided. The offset from UTC is provided when converting from UTC to a local time by calculating the difference between the original UTC and the resulting local time, but no other timezone or DST information is used.
The preferred date formatting and 12/24 hour time for the system locale can be retrieved via global preferences.
Helper functions for obtaining the day of week or day or year for calendar date, and getting the number of days in a month in a given year are provided for convenience. These are simple, but useful for performing various time related calculations.
An automated test for time conversion is included, as is a simple standalone test to display the current system date and time onscreen along with a calendar, the rendering of which demonstrates the use of the utility functions (press up/down to increment or decrement the current month, and keys 1-5 to change the date and time formats).
By using the SDL_WaitEventTimeout_Device() path even when polling is required,
we can still achieve sub-millisecond latency for non-gamepad/sensor events when
a gamepad or sensor is in use by the application.
using the blocking sceCtrlReadBufferPositive() effectively turns SDL_PollEvent() into WaitForVblank(), because the functions does exactly that if no input is buffered.
due to this, calling SDL_PollEvent() once per frame averaged in 7 ms delay out of the available 16ms budget to get a frame calculated and drawn to achieve 60 fps.
(cherry picked from commit 86f223d664)
This removes the "FSops" naming scheme, which was meant to mirror the
"RWops" naming scheme, which was also recently removed from SDL3.
The build system defines (`SDL_FSOPS_POSIX`, etc) and the source code
filenames retain this, because there's already things using the word
"filesystem" that might overlap (for example, lots of things have a
unique "SDL_sysfilesystem.c", to query base dirs, etc, but almost
everything uses the POSIX "SDL_sysfsops.c" source code.
Fixes#9288.
If someone needs to, say, include an SDL_Storage object, they can simply point userdata at a structure that includes the the storage and any other data needed in enumeration.