x11: load libXss at run time

Closes #20018
This commit is contained in:
davey authored and libretroadmin committed 2026-11-06 22:24:31 +01:00
1 parent 52488a9370
commit 8eddbf7b6a
4 files changed
+94 -11

No files matched your search

+6 -1
View File
@@ -77,8 +77,9 @@ jobs:
- name: Configure
run: |
./configure --disable-qt --disable-ffmpeg --disable-cg --disable-xscrnsaver --enable-openxr
./configure --disable-qt --disable-ffmpeg --disable-cg --enable-openxr
grep -q '^HAVE_OPENXR = 1' config.mk
grep -q '^HAVE_XSCRNSAVER = 1' config.mk
- name: Compile RA
run: make -j$(getconf _NPROCESSORS_ONLN)
@@ -86,6 +87,10 @@ jobs:
- name: Check and strip
run: |
./retroarch --version
if readelf -d retroarch | grep -q 'libXss'; then
echo 'retroarch must load libXss at run time, not link it'
exit 1
fi
strip retroarch
- name: Get short SHA
-3
View File
@@ -1374,9 +1374,6 @@ ifeq ($(HAVE_X11), 1)
LIBS += -lXi
DEFINES += -DHAVE_XI2
endif
ifeq ($(HAVE_XSCRNSAVER),1)
LIBS += -lXss
endif
ifneq ($(HAVE_OPENGLES), 1)
OBJ += gfx/drivers_context/x_ctx.o
endif
+86 -6
View File
@@ -284,10 +284,90 @@ void x11_set_window_attr(Display *dpy, Window win)
x11_set_window_pid(dpy, win);
}
#ifdef HAVE_XSCRNSAVER
#include <X11/extensions/scrnsaver.h>
#if defined(HAVE_XSCRNSAVER) && defined(HAVE_DYLIB)
#include <dynamic/dylib.h>
typedef Bool (*xss_query_extension_t)(Display*, int*, int*);
typedef Status (*xss_query_version_t)(Display*, int*, int*);
typedef void (*xss_suspend_t)(Display*, Bool);
typedef struct
{
dylib_t lib;
xss_query_extension_t query_extension;
xss_query_version_t query_version;
xss_suspend_t suspend;
} xss_t;
/* libXss is loaded on first use, so the binary starts where it is
* absent. A threaded video driver asks from its own thread; whoever
* loads first publishes. */
#ifdef RETRO_ATOMIC_HAS_PTR
static retro_atomic_ptr_t xss_published;
#else
static xss_t *xss_published;
#endif
#define XSS_SYM(field, name) \
if (!(sym = dylib_proc(t->lib, name))) \
goto fail; \
memcpy(&t->field, &sym, sizeof(sym))
static xss_t *xss_load(void)
{
function_t sym;
xss_t *t = (xss_t*)calloc(1, sizeof(*t));
if (!t)
return NULL;
t->lib = dylib_load("libXss.so.1");
#ifdef __OpenBSD__
/* OpenBSD's sonames carry its own version numbers. */
if (!t->lib)
t->lib = dylib_load("libXss.so");
#endif
if (!t->lib)
{
free(t);
return NULL;
}
XSS_SYM(query_extension, "XScreenSaverQueryExtension");
XSS_SYM(query_version, "XScreenSaverQueryVersion");
XSS_SYM(suspend, "XScreenSaverSuspend");
return t;
fail:
dylib_close(t->lib);
free(t);
return NULL;
}
static const xss_t *xss_get(void)
{
xss_t *t;
#ifdef RETRO_ATOMIC_HAS_PTR
if ((t = (xss_t*)retro_atomic_load_acquire_ptr(&xss_published)))
return t;
if (!(t = xss_load()))
return NULL;
if (!retro_atomic_cas_ptr(&xss_published, NULL, t))
{
dylib_close(t->lib);
free(t);
return (const xss_t*)retro_atomic_load_acquire_ptr(&xss_published);
}
return t;
#else
if (!xss_published)
xss_published = xss_load();
return xss_published;
#endif
}
static bool xss_screensaver_inhibit(Display *dpy, bool enable)
{
const xss_t *xss;
int dummy, min, maj;
/* Guard against being called with a NULL Display. This
* happens with the SDL2 video driver under HAVE_X11 +
@@ -302,14 +382,14 @@ static bool xss_screensaver_inhibit(Display *dpy, bool enable)
* offset off the NULL display pointer. Surfaced by the
* ASan+UBSan CI workflow's headless SDL2 smoke (b9777c8 +
* d967813), where dbus-1 isn't apt-installed but libXss is. */
if (!dpy)
if (!dpy || !(xss = xss_get()))
return false;
if ( !XScreenSaverQueryExtension(dpy, &dummy, &dummy)
|| !XScreenSaverQueryVersion(dpy, &maj, &min)
if ( !xss->query_extension(dpy, &dummy, &dummy)
|| !xss->query_version(dpy, &maj, &min)
|| (maj < 1)
|| (maj == 1 && min < 1))
return false;
XScreenSaverSuspend(dpy, enable);
xss->suspend(dpy, enable);
XResetScreenSaver(dpy);
return true;
}
+2 -1
View File
@@ -830,12 +830,13 @@ if [ "$HAVE_X11" != 'no' ]; then
check_val '' XEXT -lXext '' xext '' '' false
check_val '' XF86VM -lXxf86vm '' xxf86vm '' '' false
check_val '' XSCRNSAVER -lXss '' xscrnsaver '' '' false
check_val '' XI2 -lXi '' xi '' '' false
else
die : 'Notice: X11 not present. Skipping X11 code paths.'
fi
check_enabled X11 XSCRNSAVER XScrnSaver 'X11 is' true
check_enabled DYLIB XSCRNSAVER XScrnSaver 'Dynamic loading is' true
check_enabled X11 XINERAMA Xinerama 'Xinerama is' false
check_enabled X11 XSHM XShm 'XShm is' false
check_enabled X11 XRANDR Xrandr 'Xrandr is' false