Clamp the wl_seat max version to 5 if being built against a version of libwayland below 1.21.0, or containers that bundle newer versions of SDL with older versions of libwayland can break if the compositor advertises support for a protocol version above 5.
Depending on the underlying EGL library, it may be desirable to
conditionally set some specific EGL attributes depending on available
extensions and other application state.
SDL's EGL usage makes this a little bit complicated because:
- there are multiple functions used to set up a working EGL context
- some of these functions take different types of EGL attributes
(EGLAttrib vs EGLint)
- the EGL extension list before creating an EGLDisplay differs from the
extension list after (i.e. display vs client extensions)
- all of the above happens in a single SDL_CreateWindow call
This leaves no place for the application to discover what EGL extensions
are available and provide custom attribute lists.
Until now, if a developer wants to add a custom EGL attribute for
eglGetPlatformDisplay, eglCreateWindowSurface or eglCreateContext, they
needed to patch SDL itself. This is very undesirable, since such
developers would have to disable the SDL dynapi in order to maintain
compatibility with their needs.
This patch implements some callbacks which developers can use to
dynamically generate custom EGL attributes for SDL to use during
SDL_CreateWindow.
These functions allow applications to call EGL functions against the SDL
EGL context. For example, applications can use an EGL API loader via
SDL_EGL_GetCurrentDisplay and SDL_EGL_GetProcAddress, and can call
functions such as eglQuerySurface against the internal EGLSurface and
EGLDisplay.
The EGL 1.5 specification says that eglGetPlatformDisplay (unlike
eglGetPlatformDisplayExt) takes an EGLAttrib* rather than EGLint* for
the attribute list.
This fallback is undesirable when using ANGLE, because it will end up
using some default configuration (e.g. on Windows it defaults to the
D3D11 backend).
This implements a new SDL_GL_EGL_PLATFORM attribute to set the
"platform" argument for SDL_EGL_LoadLibrary on Windows, macOS, and
Linux. I've limited it to those three operating systems because that's
what I've been able to test against.
This adds support for forcing the use of EGL on Windows and MacOS. The
SDL_HINT_VIDEO_X11_FORCE_EGL hint is retained for backwards
compatibility but is now deprecated.
- use _Interlocked(Compare)ExchangePointer in case of _M_IX86 as well
- improve assertions:
1. add assertions to SDL_AtomicAdd/SDL_AtomicSet and SDL_AtomicCAS
2. use sizeof(a->value) instead of sizeof(int)
Sending rumble to the Amazon Luna controller on macOS gets there, but IOHIDDeviceSetReport() blocks for a long time and eventually fails.
This appears to be a bug in the macOS Bluetooth stack, ref rdar://99265496
- SDL_EventQ.active is a bool variable -> do not use SDL_AtomicGet/Set, it does not help in any way
- protect SDL_EventQ.active with SDL_EventQ.lock
- set SDL_EventQ.active to FALSE by default
This is a USB adapter for controllers shipped with Nintendo's NES-mini and
SNES-mini consoles.
Tested with both NES and SNES controllers, buttons map as expected on both.
Most of this code is disabled out for now.
- For mouse cursors we have a wl_surface for both system and custom
cursors which needs recreating.
- The other patch is about nullification after deletions
This works around udev event nodes arriving before hidraw nodes and the controller being opened twice - once using the Linux driver and once by the HIDAPI driver.
This also fixes a kernel panic on Steam Link hardware due to trying to open the hidraw device node too early.
A delay of 10 ms seems to be a good value, tested on Steam Link hardware.
If relative mouse mode is explicitly enabled, don't modify the capture flag on button events or the window might report having lost mouse focus if a button is pressed while moving the cursor.
This is a functional state for some window managers (tested using stock Ubuntu 22.04.1), and removing that state, e.g. using SDL_RestoreWindow(), results in a window centered and floating, and not visually covering the rest of the desktop.
This uses a newer browser API to get physical scancodes, but still
uses the (deprecated) event field that we were already using for
scancodes, but for keycodes instead now, which appears to be more
accurate.
Since keyboard layout isn't (generally) available to web apps, this
adds an internal interface to send key events with both scancode
and keycode to SDL's internals, instead of sending just scancodes and
expecting SDL to use its own keymap to generate keycodes.
Future work in this area would be to use the keyboard layout APIs
on browsers that support them, which would allow us to use SDL's
usual keymap code and not rely on a deprecated browser API, but
until we get there, this patch gives significantly more correct
results than we would have before.
Fixes#2098.
Exit the fullscreen sequence sooner if it is requested that a popup window be fullscreen.
The surface commit formerly in this path is irrelevant and can be removed as previous changes made it so that SetFullscreen() is no longer called from anywhere except Wayland_SetWindowFullscreen().
The controller can use either hat or buttons for the D-Pad, depending on what Linux driver is in use. The automatic mapping in LINUX_JoystickGetGamepadMapping() will do the right thing based on the exposed capability bits.
I'm sure this is the case for other controllers as well, so we might be removing more mappings over time.
Clear the window to black on the initial window draw, to avoid a really
obnoxious white flash. This doesn't always eliminate it, but it
definitely minimizes it.
This makes the colorspace match across different graphics APIs. By
default, OpenGL was getting a much more saturated colorspace (maybe
Display P3?) and it was looking very different from the rendering done
by Metal or MoltenVK.
- SDL_LoadObject: upon failure, strip the .dll extension and retry,
but only if module name has no path.
- SDL_LoadFunction: upon failure, retry with an underscore prepended,
e.g. for gcc-built dlls.
- strlcpy was passed a wrong buffer length parameter. has worked so
far by luck.
- use memcpy instead of strlcpy for simplicity.
- 'append' has been a typo: should be 'prepend'.
Otherwise the thread might block for a long time (more than 10 seconds!).
It's not clear to me why this happens, or why its safe to do this with a
resource that's still in use, but we have, until recently, always
disposed of the AudioQueue first, so changing back is probably okay.
Also changed the disposal to allow in-flight buffers to reach hardware;
otherwise you lose the last little bit of audio that's already been queued
but not played, which you can hear clearly in the loopwave test program.
Fixes#6377.
Disabling RAWINPUT on Windows 10 causes these issues:
* All Xbox controllers are named "XInput Controller".
* Trigger rumble no longer works.
* "XInput Controllers" are now also listed as separate haptic devices
It's only needed to support more than 4 Xbox controllers, and adds significant complexity to the joystick processing, and we regularly get bugs from people who aren't using an SDL window who need to turn on SDL_HINT_JOYSTICK_THREAD.
Replace instances of fprintf(stderr, ...) with SDL_SetError(), replace C++ comments with C style, use a uniform format for multi-line comments, and remove unused headers as poll and select aren't used in this file (the SDL function which calls them is used instead).
libdecor_dispatch() needs to be called, as libdecor plugins might do some required internal processing within, however care must be taken to avoid double-blocking in the case of a timeout, which can occur if libdecor_dispatch() and the SDL event processing both work on the main Wayland queue. Additionally, assumptions that libdecor will always dispatch the main queue or not process zero-length queues (can occur if a wait is interrupted by the application queueing an event) should not be made, as this behavior is outside the control of SDL and can change.
SDL handles polling for Wayland events and then calls libdecor to do its internal processing and dispatch. If libdecor operates on the main queue, it will dispatch the queued events and the additional wl_display_dispatch_pending() call will be a NOP. If a libdecor plugin uses its own, separate queue, then the wl_display_dispatch_pending() call will ensure that the main queue is always dispatched.
Fixes battery level dropping to empty with the Qanba Drone Arcade Stick.
It looks like we might also be able to skip the check for all third party controllers, but I think this is the right thing to do for Sony controllers as well.
In all cases they were using SDL_SCANCODE_TABLE_XFREE86_2 with some keycodes remapped or fewer than expected keycodes. This adds a sanity check that catches all of them and gives them the right scancode table.
If we can't find the X11 keysym, it's likely that either the keysym is NoSymbol, in which case we won't hit it anyway, or it's been mapped to a character, in which case the existing mapping is correct for the scancode and the character will be reflected in the keycode mapping.
* Consolidated scancode mapping tables into a single location for all backends
* Verified that the xfree86_scancode_table2 is largely identical to the Linux scancode table
* Updated the Linux scancode table with the latest kernel keycodes (still unmapped)
* Route X11 keysym -> scancode mapping through the linux scancode table (which a few hand-written exceptions), which will allow mappings to automatically get picked up as they are added in the Linux scancode table
* Disabled verbose reporting of missing keysym mappings, we have enough data for now
The original code mapped incorrectly from [min, max] to [-32768, 32512], the upper bound being SDL_JOYSTICK_AXIS_MAX - 255 instead of SDL_JOYSTICK_AXIS_MAX.
This will only log things going through dynapi, which means it won't
do anything if dynapi is disabled for a given build, but also things
that call the `*_REAL` version of an API won't log either (which is
to say, if an internal piece of SDL calls a public API, it won't log
it, but if an application calls that same entry point, it will).
Since this just inserts a different function pointer, unless you
explicitly request this at runtime, it won't add any overhead, and,
of course, the entire thing can be turned off with a single #define
so it doesn't even add extra unused code to the shared library if
the kill switch is flipped.
These were needed to fix some buggy behavior regarding committing old buffer sizes when entering fullscreen that has since been corrected. Remove them.
If the compositor is entering fullscreen and hasn't removed any constraints itself, it's already too late at this point. Remove the unnecessary call.
Restoring the limits when exiting fullscreen is still required, though, as they may have been removed when entering fullscreen via an SDL request.
Caches the SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY hint at init time and registers a callback, which is fired when the hint is changed during runtime and toggles the opaque region for existing surfaces.
The preferred method for setting the damage region on compositor protocol versions 4 and above is to use wl_surface.damage_buffer. Use this when available and only fall back to wl_surface.damage on older versions.
Bumps the highest supported version of wl_compositor to version 4.
Adds deduplication logic to ConfigureWindowGeometry() to avoid setting redundant backbuffer, viewport and surface opaque region dimensions. State is now only set when the window and/or backbuffer dimensions change.
This repurposes the viewport rect to always hold the actual size of the window, which can differ from the SDL size if things are being scaled. The SDL_Rect was removed in favor of two ints, as the x/y members of the struct were never used, so they just wasted space.
Since the internal variables always have the true window size, the width/height getter functions are no longer required and can be removed.
Several games (including Source and GoldSrc games, and Bioshock
Infinite) attempt to "fake" relative mouse mode by repeatedly warping
the cursor to the centre of the screen. Since mouse warping is not
supported under Wayland, the viewport ends up "stuck" in a rectangular
area.
Detect this case (mouse warp while the cursor is not visible), and
enable relative mouse mode, which tracks the cursor position
independently, and so can Warp successfully.
This is behind the SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP hint, which
is enabled by default, unless the application enables relative mouse
mode itself using SDL_SetRelativeMouseMode(SDL_TRUE).
Note that there is a behavoural difference, in that relative mouse mode
typically doesn't take mouse accelleration into account, but the
repeated-warping technique does, so mouse movement can seem very slow
with this (unless the game has its own mouse accelleration option, such
as in Portal 2).
Make sure the SDL java and C code match when updating SDL in a game.
Right now we're assuming that we only have to make sure release versions match. We can extend the version string with an interface version if we need more fine grained sanity checking.
Fixes https://github.com/libsdl-org/SDL/issues/1540
This is the only case where the mapping differs between right and left Joy-Cons in mini-gamepad mode. The left Joy-Con will have the left paddles and the right Joy-Con will have the right paddles. This facilitates co-op gameplay with individual actions while still using the normal mini-gamepad mode.
The paddles are used for this because conceptually they are more awkward to hit than the normal controls and they are in roughly the correct hand position.
* Added support for vertical mode for Joy-Con controllers
* Added the hint SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS for switching to this mode
* Added support for SL/SR buttons in combined/vertical mode and L/ZL/R/ZR buttons in mini-gamepad mode
Calling SDL_HideWindow() to destroy the window is a NOP if the SDL_WINDOW_SHOWN flag was never set. Bypass it and call the Wayland-specific function directly to ensure that the window is always destroyed before switching from server-side to client-side decorations, even if it hasn't been shown yet.
Likewise, call Wayland_ShowWindow() directly when the window isn't explicitly hidden to ensure that it is always recreated since the SDL_WINDOW_SHOWN flag won't be cleared, which, when set, renders SDL_ShowWindow() a NOP.
Before calling any D-Bus related methods we should first ensure that
they
were correctly loaded.
In the event where `LoadDBUSLibrary()` was not able to load the D-Bus
library, we should just return early, signalling with SDL_FALSE that we
were unable to inhibit the Screensaver.
Helps: https://github.com/ValveSoftware/steam-for-linux/issues/8815
Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
ad874536 removed an unnecessary limit as we *can* have a devindex
greater than 99, this error message does not reflect the support for
values greater than 99.
If a Nintendo Switch Pro controller is turned off, it will leave the controller connected in Windows, but not responding to reports. Don't wait a really long time trying to get information from a controller in this state.
On Windows, the Bluetooth device can remain in a connected state if the controller just shut down. It won't return any errors, but it also won't generate any input reports in this state, so wait until we know for sure that the Bluetooth controller is sending data before letting the application know it's available.
Nintendo Switch controllers will automatically turn off Bluetooth when connected over USB, but this takes care of that a little more quickly.
PS4 and PS5 controllers will happily send reports over both Bluetooth and USB, so we'll prefer USB if connected and switch back to Bluetooth if USB is disconnected.
The text component of a repeated keystroke is initially set when a key is first pressed and the cached value remains static until the repeated key is released and another repeatable key is pressed. If the state of a modifier such as shift or capslock is changed while a key is being repeated, the text emitted will not have the modifier applied to it until the repeated key is released and pressed again.
Update the text to be repeated by a key if a modifier is changed while a key is actively being repeated.
The XKB keysym to SDL keycode mappings were missing for the Escape and NumLock keys, which prevented them from being remapped. Add them to the table so that the remapping of these keys will work.
Note that returning SDL_PIXELFORMAT_BGR24 instead of SDL_PIXELFORMAT_RGB24 seems necessary, otherwise when running with SDL_ACCELERATION=0, the red and blue channels of the window appeared swapped.
Note that when running with acceleration enabled, red and blue channel swapping does not happen regardless of whether SDL_PIXEL_FORMAT_RGB24 or SDL_PIXEL_FORMAT_BGR24 is returned.
For good measure, I also tested running with acceleration disabled in both 15 and 16 bit color depths, but red and blue channel swapping did not occur
This prevents a number of issues where devices are enumerated but not actually able to be opened, like https://github.com/libsdl-org/SDL/issues/5781.
We currently leave the devices open, allowing us to more easily do controller feature detection, protocol negotiation, detect dropped Bluetooth connections, etc. with the expectation that the application is likely to open the controllers shortly.
If multiple keys were simultaneously depressed and one was being repeated, the repeat flag was being cleared when any of the pressed keys were released, even if the released key wasn't the one being repeated.
This tracks the key currently being repeated and only clears the repeat flag when the particular key being repeated is released.
Silences clang -Wpragma warnings:
D:/a/SDL/SDL/src/video/windows/SDL_windowstaskdialog.h:21:10: warning: the current #pragma pack alignment value is modified in the included file [-Wpragma-pack]
#include <pshpack1.h>
^
D:/a/_temp/msys64/clang64/include/pshpack1.h:7:9: note: previous '#pragma pack' directive that modifies alignment is here
#pragma pack(push,1)
^
In file included from D:/a/SDL/SDL/src/video/windows/SDL_windowsmessagebox.c:35:
D:/a/SDL/SDL/src/video/windows/SDL_windowstaskdialog.h:156:10: warning: the current #pragma pack alignment value is modified in the included file [-Wpragma-pack]
#include <poppack.h>
^
note: previous '#pragma pack' directive that modifies alignment is here
2 warnings generated.
Closes: https://github.com/libsdl-org/SDL/issues/6240
Unfortunately the only way to detect this is to actually try opening a device, so we wait until the application tries, and then stop enumerating afterwards.
Fixes https://github.com/libsdl-org/SDL/issues/5781
This kicks in if the platform doesn't support vsync directly, or if the present fails for some reason (e.g. minimized on some platforms)
Fixes https://github.com/libsdl-org/SDL/issues/5134
X11 has a so-called primary selection, which you can use by marking text and middle-clicking elsewhere to copy the marked text.
There are 3 new API functions in `SDL_clipboard.h`, which work exactly like their clipboard equivalents.
## Test Instructions
* Run the tests (just a copy of the clipboard tests): `$ ./test/testautomation --filter Clipboard`
* Build and run this small application:
<details>
```C
#include <SDL.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void print_error(const char *where)
{
const char *errstr = SDL_GetError();
if (errstr == NULL || errstr[0] == '\0')
return;
fprintf(stderr, "SDL Error after '%s': %s\n", where, errstr);
SDL_ClearError();
}
int main()
{
char text_buf[256];
srand(time(NULL));
SDL_Init(SDL_INIT_VIDEO);
print_error("SDL_INIT()");
SDL_Window *window = SDL_CreateWindow("Primary Selection Test", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 400, 400, SDL_WINDOW_SHOWN);
print_error("SDL_CreateWindow()");
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
print_error("SDL_CreateRenderer()");
bool quit = false;
unsigned int do_render = 0;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
print_error("SDL_PollEvent()");
switch (event.type) {
case SDL_QUIT: {
quit = true;
break;
} case SDL_KEYDOWN: {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_q:
quit = true;
break;
case SDLK_c:
snprintf(text_buf, sizeof(text_buf), "foo%d", rand());
SDL_SetClipboardText(text_buf);
print_error("SDL_SetClipboardText()");
printf("clipboard: set_to=\"%s\"\n", text_buf);
break;
case SDLK_v: {
printf("clipboard: has=%d, ", SDL_HasClipboardText());
print_error("SDL_HasClipboardText()");
char *text = SDL_GetClipboardText();
print_error("SDL_GetClipboardText()");
printf("text=\"%s\"\n", text);
SDL_free(text);
break;
} case SDLK_d:
snprintf(text_buf, sizeof(text_buf), "bar%d", rand());
SDL_SetPrimarySelectionText(text_buf);
print_error("SDL_SetPrimarySelectionText()");
printf("primselec: set_to=\"%s\"\n", text_buf);
break;
case SDLK_f: {
printf("primselec: has=%d, ", SDL_HasPrimarySelectionText());
print_error("SDL_HasPrimarySelectionText()");
char *text = SDL_GetPrimarySelectionText();
print_error("SDL_GetPrimarySelectionText()");
printf("text=\"%s\"\n", text);
SDL_free(text);
break;
} default:
break;
}
break;
} default: {
break;
}}
}
// create less noise with WAYLAND_DEBUG=1
if (do_render == 0) {
SDL_RenderPresent(renderer);
print_error("SDL_RenderPresent()");
}
do_render += 1;
usleep(12000);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
print_error("quit");
return 0;
}
```
</details>
* Use c,v,d,f to get and set the clipboard and primary selection.
* Mark text and middle-click also in other applications.
* For wayland under x:
* `$ mutter --wayland --no-x11 --nested`
* `$ XDG_SESSION_TYPE=wayland SDL_VIDEODRIVER=wayland ./<path_to_test_appl_binary>`
Clip rectangle set to int(left+width/2) , int(top+height/2) , int(left+width/2)+1 , int(top+height/2)+1
a 1x1 box
On even-valued resolution, cursor is stable at bottom-right central pixel
On odd-valued resolution, cursor is stable at exact central pixel.
this is the desired behaviour
In some cases, a backbuffer size update may not be accompanied by a resize event if the window size and/or scale were updated before the new backbuffer size was recomputed. Instead of the scale, use the old/new backbuffer sizes to determine if a resize event is required so that a backbuffer size change will always be followed by a resize event.
Instead of wrapping individual calls to SDL_SetDisplayModeForDisplay(), just check the flag in the function itself and make it a NOP that cannot fail if the flag is set. Silences some errant "SDL video driver doesn't support changing display mode" log errors.
When hiding a window, libdecor can report bogus content region sizes that are +/- the height of the title bar. Ignore any size values from libdecor when hiding a window, or the size may be incorrect when restored.
The compositor can arbitrarily move windows between displays, including fullscreen windows. Update the internal state when a fullscreen window is moved so the internal SDL state accurately reflects the window location, and resize the window to fit the new display.
This also fixes an edge case where the compositor can make a window fullscreen on a different display than SDL thinks it will be on (usually when a window is made fullscreen by the compositor while straddling multiple displays), which can result in the window being incorrectly sized.
If additional fullscreen requests are received when the window is already fullscreen, it is typically due to the fullscreen flags or emulated video mode being changed. A commit must be explicitly triggered or the requested changes won't take effect until some other event, such as a resize or focus change, causes the changes to be committed.
The compositor can toggle the fullscreen state (via a hotkey or otherwise), so the internal SDL state must be updated accordingly when it does.
When toggling fullscreen via the compositor, SDL will attempt to use the last fullscreen flag explicitly set. If no flag was previously set, SDL_WINDOW_FULLSCREEN will be used if a window video mode was set, otherwise SDL_WINDOW_FULLSCREEN_DESKTOP will be used. If the previous flag was SDL_WINDOW_FULLSCREEN and the window video mode was cleared, it will revert to SDL_WINDOW_FULLSCREEN_DESKTOP.
SDL_Quit() should be the last SDL API that you call before exiting your application, and is intended to clean up all internal state.
If real-life applications are relying on thread-local storage after SDL_Quit() we could potentially add a hint to control this behavior.
Fixes https://github.com/libsdl-org/SDL/issues/6200
DS4Windows can create both emulated Xbox and emulated PS4 controllers, and we don't know which the user has it doing, so don't try to second guess it, just let it do it's thing. Users should follow the remapping software recommendations on when to enable/disable it for various situations.
Fixes https://github.com/libsdl-org/SDL/issues/6167
There is supposedly an OpenGL ES2 target that does not support precision specifiers. However, the existing logic to detect this is currently broken in two ways:
1) There's a typo of the `#ifdef` as `#if`.
2) Checking for `GL_FRAGMENT_PRECISION_HIGH` can not be the correct way to detect this platform. Other targets, including some desktops, will also not have this defined (for various reasons).
Because some of the shader code is missing precision specifiers, and because a default is ONLY provided if `GL_FRAGMENT_PRECISION_HIGH` is set, these other targets break.
Instead of 'hard-coding' the prologue string into shaders in the C source, use our ability to provide a list of strings to `glShaderSource` instead, leaving the determination to run-time.
This commit closes https://github.com/libsdl-org/SDL/pull/6182