Here's an IRC dump that hopefully explains the issue this fixes:
> I'm debugging something odd where, for a libre game,
unvanquished.net (a FPS), relative mouse input in fullscreen is
buggy
> it's like, working mostly ok, but it has a weird
performance/cleanup bug
> after some time in relative mouse input mode, some time as low
as 15s, usually more, the SDL sends A LOT of relative mouse
input per frame
> almost all of which have xrel==0 && yrel==0
> by A LOT, I mean that after ~1min, it's usually in the
thousands per frame
> each frame, a while ( SDL_PollEvent( &e)) loop reads the
inputs, but it seems SDL is not clearing the list.
> one way to clear the list is to open the in-game console or
menu, which switches the input mode to absolute, then close it
which gets a working relative input mode (for some time at least)
> I've shown the issue to be present with SDL2.0.20 but not with
2.0.14 on my system
> some other players on Arch Linux (SDL2.0.20) report a possibly
related issue, where some keys seem to be pressed at random
> I've did some bisection on SDL master, and I've found that
there are actually two commits involved, one breaking it
totally (no input at all), and one fixing it partially (with
the problem described above)
First related commit that breaks it totally:
commit 82793ac279
Author: Sam Lantinga <slouken@libsdl.org>
Date: Thu Oct 14 14:26:21 2021 -0700
Fixed mouse warping while in relative mode
We should get a mouse event with an absolute position and no relative motion and shouldn't change the OS cursor position at all
Second related commit, that halfway fixes it:
commit 31f8c3ef44
Author: Sam Lantinga <slouken@libsdl.org>
Date: Thu Jan 6 11:27:44 2022 -0800
Fixed event pump starvation if the application frequently pushes its own events
Reverting the first commit did fix the issue for me, but would
probably reintroduce the bug it was fixing(?). This patch should
fix it for everyone hopefully.
https://github.com/DaemonEngine/Daemon/issues/600 is the upstream
bug, and contains some early investigation.
According to MSDN, we can also get SIZE_MAXHIDE and SIZE_MAXSHOW,
based on state changes to other windows. It's not clear under
what circumstances this will happen (I saw some docs indicating
it may require multiple application windows), but it doesn't seem
right to treat them as RESTORED.
- no need to keep the error in a static variable
- always print the error code
- reduce the required stack-size
- reduce the number of snprintf calls (and code size)
* Fixes for IME Composition Truncation + Addition of SDL_ClearComposition, SDL_IsTextInputShown
* Fixed: Documentation and code style issues raised during code review.
The name that the Raw Input joystick driver pulls from the HID stack comes
from USB string descriptors contained on the device. For official wireless
receivers, this always contains "Xbox 360 Wireless Receiver for Windows"
which matches the friendly name that WGI provides.
3rd party Xbox 360 wireless receivers may have different strings in their
USB string descriptors (one uses "XBOX 360 For Windows" instead). This
fails to match WGI's name and causes Raw Input and WGI to both report the
same gamepad.
Since wireless Xbox 360 controllers seem to have a consistent VID/PID
regardless of the adapter enumerating them, we can also match on that to
catch these.
The duplicate case reported to me was:
Controller (XBOX 360 For Windows) - 030000005e040000a102000000007200
Xbox 360 Wireless Receiver for Windows - 030000005e0400000000000000007701
This adds support for all 3 of the gamecube controller's rumble modes
Rumble: 1
Stop: 0
StopHard: 2
This is useful for applications that need the full range of support
This also adds a hint to control rumble behavior, defaults 0 to maintain compatibility
If the app requested a specific renderer, even if it's not the optimal path,
let them have it, because they might want to render with a specific GPU API
on top of the framebuffer pixels.
This fixes DosBox-X crashing on startup, which forces the hint to "opengl".
Now we see if we can create an SDL_Renderer, and if that renderer reports
itself as "accelerated," and added some initial heuristics to the OpenGL
renderer to make better decisions about what qualifies as "accelerated."
This adds some FIXMEs that might be merely hypothetical, and removes the
old OpenGL checks from the video subsystem that probably weren't meaningful
in modern times. This will definitely need to improve the existing list
in the GL renderer, to catch things like llvmpipe, etc.
Reference issue #4624.
The io_list_check_add() and io_list_remove() functions are only ever called from within the Pipewire thread loop, so the locks are redundant. io_list_sort() is called from within a lock in the device detection function, so those additional locks are redundant as well.
Remove the hard upper limit of 8192 samples and instead use the buffer sizes provided by Pipewire to determine the size of the intermediate input buffer and whether double buffering is required for output streams. This allows for higher latency streams to potentially avoid double-buffering in the output case, and we can guarantee that the intermediate input buffer will always be large enough to handle whatever Pipewire may deliver.
As the buffer size calculations occur in a callback in the Pipewire processing thread itself, the stream readiness check has been modified to wait on two distinct flags set when the buffers have been configured and when the stream is ready and running.
- use the result of SDL_ConvertPixels to propagate error
- get rid of the verbose error message of D3D11_RenderReadPixels in case SDL_ConvertPixels failed
- always set error message in SDL_EGL_ChooseConfig / SDL_EGL_CreateContext
- assume SDL_EGL_DeleteContext does not alter the error message
- sync generic error message of SDL_EGL_MakeCurrent with SDL_EGL_Get/SetSwapInterval
- do not overwrite error message of SDL_EGL_ChooseConfig in WINRT_CreateWindow
- add missing error-message in SDL_LoadBMP_RW
- check return value of SDL_RWtell in SDL_LoadBMP_RW
- use standard SDL_EFREAD error instead of custom strings
+ adjust return type of readRlePixels
- allocate ime_candidates on demand
- allow write to the whole allocated memory of ime_candidates
- ensure ime_candcount is set to zero in case the candidates can not be queried for any reason
- move IME_ShowCandidateList, ImmGetContext and ImmReleaseContext to this function
- set ime_candpgsize to MAX_CANDLIST if dwPageSize is zero
- comment out deselection of ime_candsel in case of korean language for the moment (LANG_CHT does not work anyway)
The context and stream creation functions will destroy the passed properties object on failure, so no need to do it manually.
The pw_properties_free() function pointer is no longer needed, so it can be removed.
This reverts commit ca36cdb185f2f26241598068927821896f36b904.
The older Windows SDK's headers are wrong, and this change would crash if
you hotplug a device.
- drop unnecessary hascapture check
- call SDL_InvalidParamError and return -1 in case the index is out of range
- do not zfill SDL_AudioSpec
- adjust documentation to reflect the behavior
- reorganize the loop which checks for the right wave-format
- use the return value of UpdateAudioStream
- ensure SetError is called in SDL_NewAudioStream
- use assert instead of a check (it is a static function with constant parameter)
- assume it is called with 0 first (simplifies the logic)
- reuse dwLang value instead of a new 'call' to LANG()
- use SDL_bool if possible
- assume NULL/SDL_FALSE filled impl
- skip zfill of current_audio at the beginning of SDL_AudioInit (done before the init() calls)
If we get a SDL_SetWindowSize() call right after SDL_SetWindowFullscreen() but
before we've gotten a new configure event from the compositor, the attempt to
set our window size will silently fail (when libdecor is enabled).
Fix this by remembering that we need to commit a new size, so we can do that
in decoration_frame_configure().
This prevents SDL from making an OpenGL context and maybe throwing it away
immediately by default. It will now only do it when trying to request a
window framebuffer directly, or creating an SDL_Renderer with the "software"
backend, which makes that request itself.
The way SDL decides if it should use a "texture framebuffer" needs dramatic
updating, but this solves the immediate problem.
Reference Issue #4624.
First window is created and it triggers and 'EnterNotify' event
which calls SDL_SetMouseFocus() and X11_ShowCursor() while the second
windows hasn't finished to be created (eg window->driverdata isn't set)
Just check for a valid 'driverdata'
The issue is that MS Windows synthesizes a mouse-move event in response
to touch-move events, and those mouse-move events are NOT labeled as
coming from a touch (e.g. GetMouseMessageSource() will not return
SDL_MOUSE_EVENT_SOURCE_TOUCH for those synthesized mouse-move events).
In addition, there seems to be no way to prevent this from happening;
https://gist.github.com/vbfox/1339671 claims to demonstrate a technique
to prevent it, but in my experience, it doesn't work.
Because of this, the "fallthrough" case can't test that the synthesized
mouse-move came from a touch-move, and starts erroneously pressing down
the mouse-button, leading to massive confusion in the client
application.
If a touch-down event is received for an existing touch-ID, that
probably means the operating system lost it, and that the missing
touch-up should be synthesized, to keep the client state coherent.
This caused some weird stuff to happen in the libdecor path, probably because
the window hasn't actually been mapped yet. It ends up calling stuff that
should not yet apply, and so fullscreen in particular would have a really
messed up titlebar.
The good news is, libdecor is good about tracking fullscreen state, so we can
let the callback do this for us. Keep this for xdg_shell because we actually
map the window ourselves, so we know this call is valid for that path.
Pipewire, as of 0.3.22, uses client config files to load modules instead of explicitly specifying them (PW_KEY_CONTEXT_PROFILE_MODULES is deprecated). Use the new method to load the realtime module to boost the audio thread priority.
From e6cc4e7f4b8189be55dd3b0e13e54e59f73d7672 Mon Sep 17 00:00:00 2001
From: X512 <danger_mail@list.ru>
Date: Thu, 30 Jan 2020 04:01:58 +0900
Subject: libsdl2: Remove BDirectWindow, fix OpenGL handling.
* BDirectWindow changed to BWindow.
* Implemented fullscreen.
* Introduced view for non-OpenGL drawing.
* Drawing thread removed, window thread is used instead.
* Use BGLView as OpenGL context. Implement proper context switching and OpenGL
locking. Only one context per window is supported. BGLView should be not
deleted when window is closed, it deleted when deleting context.
Previous to this commit, key repeats events were typically generated when
pumping events, based on the time of when the events are pumped. However,
if an application doesn't call `SDL_PumpEvents` for some seconds, this time
can be multiple seconds in the future compared to the actual key up event time,
and generates key repeats even if a key was pressed only for an instant.
In practice, this can happen when the user presses a key which causes the
application to do something without pumping events (e.g. load a level).
In Crispy Doom & PrBoom+, when the user presses the key bound to "Restart
level/demo", the game doesn't pump events during the "screen melt" effect,
and the level is restarted multiple times due to spurious repeats.
To fix this, if the key up event is among the events to be pumped, we generate
the key repeats there, since in the Wayland callback we receive the time when
the key up event happened. Otherwise, we know no key up event happened and we
can generate as many repeats as necessary after pumping.
Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
Refactorization with no functional changes.
Instead of `next_repeat_ms` containing a timestamp based on SDL ticks, we make
it zero-based relative to the key press time, and we store the key press time in
SDL ticks in a new field.
This refactorization is groundwork for future commits which need to use the
key press and release timestamps provided by the Wayland API, which are also
expressed in milliseconds, but whose base does not match the one for SDL ticks.
Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
If `repeat_info->next_repeat_ms` overflows, many key presses will be generated.
In the worst case, `now = 0xFFFFFFFFU` and the loop will never terminate.
Rearrange the comparison in order to gracefully handle the overflow case.
Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
src/render/psp/SDL_render_psp.c: In function 'PSP_RunCommandQueue':
src/render/psp/SDL_render_psp.c:1200: warning: passing argument 1 of 'PSP_SetBlendState' from incompatible pointer type
src/filesystem/psp/SDL_sysfilesystem.c: In function 'SDL_GetPrefPath':
src/filesystem/psp/SDL_sysfilesystem.c:71: warning: passing argument 1 of 'free' discards qualifiers from pointer target type
This reverts commit c477768e6f.
We want to add the sentinel anytime we pump inside SDL_WaitEventTimeout() to avoid pumping again the next time through, as a performance optimization.
We don't want to catch explicit SDL_PumpEvents() calls by the application with
our polling check to avoid stale data. If the call to SDL_PumpEvents() produced
no events, there will be a sentinel sitting in the queue that will cause
SDL_PollEvent() to immediately return 0 next time it is called.
Our SDL_WaitEventTimeout() implementation avoids this issue by always popping
an event after calling SDL_PumpEvents(). This will remove the new sentinel if
we didn't get any new events.
WGI calls SDL_DINPUT_JoystickPresent() so we need to be sure DInput remains
initialized for the lifetime of the WGI driver to avoid a crash or duplicated
joysticks between DInput and WGI.
If that condition was reachable, the return value should be negative to indicate that waiting for the timeout failed.
Otherwise, SDL_WaitEventTimeout would incorrectly return early.
SDL_Init(SDL_INIT_AUDIO) did not take into account that functions like
SDL_AddAudioDevice do register events, which will need final cleanup
and only gets fired when events were actually initialised.
Sample call stack of a malloc missing its free (Linux + PA):
SDL_malloc_REAL (SDL_malloc.c:5328)
SDL_AddEvent (SDL_events.c:445)
SDL_PeepEvents_REAL (SDL_events.c:531)
SDL_PushEvent_REAL (SDL_events.c:762)
SDL_AddAudioDevice (SDL_audio.c:443)
SourceInfoCallback (SDL_pulseaudio.c:681)
context_get_source_info_callback (introspect.c:534)
run_action (pdispatch.c:288)
pa_pdispatch_run (pdispatch.c:341)
pstream_packet_callback (context.c:349)
do_read (pstream.c:1012)
Fixes https://github.com/libsdl-org/SDL/issues/3005
When mouse buttons are swapped, right mouse button down is the same value as raw mouse button up, and conceptually the two systems use different button masks, so never cache state between the two.
Fixes https://github.com/libsdl-org/SDL/issues/5108
Program received signal SIGILL, Illegal instruction.
X11_InitKeyboard (_this=0x1001f8f0)
at /home/sdl/SDL_git/src/video/x11/SDL_x11keyboard.c:273
273 XKeyboardState values = { .global_auto_repeat = AutoRepeatModeOff };
If the X server's byte order is different from the client, things might
display in the wrong colour.
Apparently we can just set the byte_order field to the client's byte
order, and the X server will adjust everything automatically:
https://xorg.freedesktop.narkive.com/GbSD1aPq/ximage-s-byte-order-field
because:
- GeHint return a value pointer.
- SetHint free internally the pointer
- The -now invalid- pointer is re-read
==9363== Invalid read of size 1
==9363== at 0x4946860: SW_CreateRenderer (SDL_render_sw.c:1044)
==9363== by 0x48F0EC3: SDL_CreateRenderer_REAL (SDL_render.c:938)
==9363== by 0x48C5921: SDL_CreateRenderer (SDL_dynapi_procs.h:332)
==9363== by 0x401584: main (main.c:421)
==9363== Address 0x9c24040 is 0 bytes inside a block of size 1 free'd
==9363== at 0x484621F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9363== by 0x494E403: SDL_free_REAL (SDL_malloc.c:5432)
==9363== by 0x48A6153: SDL_SetHintWithPriority_REAL (SDL_hints.c:76)
==9363== by 0x48A6254: SDL_SetHint_REAL (SDL_hints.c:101)
Rounding the scroll deltas from trackpads causes jerky scrolling behavior
by artificially amplifying the effects of very small scroll movements.
We should only round events from devices with discrete scroll wheels,
because we know the smallest unit of movement there is a single tick.
- Fix SDL2main on PSP
SDL2main was not working for PSP, because it wasn't being activated and
it wasn't unsetting the main. Besides that a debug screen being started
was causing issues with joystick input and the sceKernelExitGame calli
is no longer needed with the current PSPDEV SDK.
- Clean up imports in PSP main
- Set PSP GPU and user modes in main
- Fix exit callback in PSP main
The xdg_shell spec seems to state[1] that xdg_toplevel_configure events can
always provide a 0×0 width/height to signal that the compositor doesn't
care. SDL previously assumed the provided width/height was always valid
for fullscreen windows, and so applied it as-is.
This broke SDL applications on KDE/KWin 5.23, which now sends 0×0
configure events (and, in 5.23.3, 1×1 events for some reason), breaking
all SDL applications in fullscreen[2].
[1]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/6
[2]: https://bugs.kde.org/show_bug.cgi?id=444962#c6
Otherwise, if one builds libSDL2_test using a new mingw but builds
the test programs using an older mingw, a link failure happens:
/opt/local/x86_64-w64-mingw32/lib/libSDL2_test.a(SDL_test_common.o): In function `printf':
/opt/local/x86_64-w64-mingw32/include/stdio.h:372: undefined reference to `__imp___acrt_iob_func'
collect2: ld returned 1 exit status
gbm_device_get_fd() in at least some libmali versions duplicates handle.
Other implementations do not do duplication. To prevent handle leak save
drm_fd in SDL_DisplayData.
When our keyboard grab hook is installed, GetKeyState() will return 0 for the
GUI keys even when they are pressed. This leads to spurious key up events when
holding down the GUI keys and the inability to use any key combos involving
those modifier keys.
This fixes a compile warning — and possible invalid memory read —
introduced in 9c03d255 ("Add back X11 legacy WM_NAME encodings"), which
was part of PR #5029, fixing Bug #4924.
The issue is with one of the added warnings in X11_GetWindowTitle().
Basically, the "title" variable passed to SDL_LogError() hasn't been
initialised yet: we could pass propdata in directly, but it's better to
move the SDL_LogError() call until after title is set, IMHO.
This fixes the following warning from gcc (SUSE Linux) 11.2.1:
In file included from /home/david/Development/SDL/src/video/x11/../../SDL_internal.h:45,
from /home/david/Development/SDL/src/video/x11/SDL_x11window.c:21:
/home/david/Development/SDL/src/video/x11/SDL_x11window.c: In function 'X11_GetWindowTitle':
/home/david/Development/SDL/src/video/x11/../../dynapi/SDL_dynapi_overrides.h:33:22: warning: '%s' directive argument is null [-Wformat-overflow=]
33 | #define SDL_LogDebug SDL_LogDebug_REAL
/home/david/Development/SDL/src/video/x11/SDL_x11window.c:720:13: note: in expansion of macro 'SDL_LogDebug'
720 | SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Failed to convert WM_NAME title expecting UTF8! Title: %s", title);
| ^~~~~~~~~~~~
Closes#4924.
Based on patches of the past, such as this work by James Cloos in July
2010:
d7d98751b7,
as well as code comments in the Perl module X11::Protocol::WM
(https://metacpan.org/pod/X11::Protocol::WM) and even the code to Xlib
itself, which taught me that we should never have been using
`XStoreName`, all it does is call `XChangeProperty`, hardcoded to
`XA_STRING`!
What can I say, when the task is old school, the sources are too 😂
On Win32 this list is empty and we always get controller added events. On UWP, this list is populated and we don't get controlle added events for currently connected controllers.
This is to workaround systems where we hang in playback because the buffer
does not report the space for whatever reason. The system will instead block
in PlayDevice, which always immediately follows WaitDevice in modern times
so this works out, and it seems to keep the device moving forward.
For a future revision, we are either going to clean this up more properly,
or attempt to move to PulseAudio's pa_stream_set_write_callback() API, but
this will do for SDL 2.0.18.
Reference #4387 for discussion and further information.