From a253869c24b462c75127d1065330aba1c9bb520d Mon Sep 17 00:00:00 2001 From: Slendi Date: Tue, 30 Sep 2025 09:53:53 +0300 Subject: [PATCH] yea Signed-off-by: Slendi --- src/egl_override.c | 106 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/egl_override.c diff --git a/src/egl_override.c b/src/egl_override.c new file mode 100644 index 0000000..f2a57eb --- /dev/null +++ b/src/egl_override.c @@ -0,0 +1,106 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +// Some drivers expose EGL_EXT_create_context_robustness, which wlroots +// consumes to request EGL_LOSE_CONTEXT_ON_RESET_EXT. Monado rejects sharing +// contexts with mismatched reset notification strategies, so hide that +// extension from wlroots by overriding eglQueryString. + +typedef const char *(*eglQueryStringFn)(EGLDisplay display, EGLint name); + +static const char *strip_extension(const char *exts, const char *target) +{ + if (!exts || !target || *target == '\0') { + return exts; + } + + size_t target_len = strlen(target); + const char *found = strstr(exts, target); + if (!found) { + return exts; + } + + char *copy = strdup(exts); + if (!copy) { + return exts; + } + + char *start = strstr(copy, target); + while (start) { + char *end = start + target_len; + + // Trim leading spaces before the target substring. + while (start > copy && start[-1] == ' ') { + start--; + } + + // Skip trailing spaces after the target substring. + while (*end == ' ') { + end++; + } + + memmove(start, end, strlen(end) + 1); + start = strstr(start, target); + } + + // Collapse duplicate spaces introduced by removals. + char *dst = copy; + bool prev_space = false; + for (char *src = copy; *src; ++src) { + if (*src == ' ') { + if (prev_space) { + continue; + } + prev_space = true; + } else { + prev_space = false; + } + *dst++ = *src; + } + // Trim any trailing space left at the end. + if (dst > copy && dst[-1] == ' ') { + --dst; + } + *dst = '\0'; + + return copy; +} + +const char *eglQueryString(EGLDisplay display, EGLint name) +{ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static eglQueryStringFn real_eglQueryString = NULL; + static const char *cached_extensions = NULL; + + if (!real_eglQueryString) { + real_eglQueryString = (eglQueryStringFn)dlsym(RTLD_NEXT, "eglQueryString"); + if (!real_eglQueryString) { + fprintf(stderr, "lunarwm: failed to resolve real eglQueryString\n"); + return NULL; + } + } + + const char *result = real_eglQueryString(display, name); + if (name != EGL_EXTENSIONS || result == NULL) { + return result; + } + + pthread_mutex_lock(&mutex); + if (cached_extensions == NULL) { + cached_extensions = strip_extension(result, "EGL_EXT_create_context_robustness"); + if (cached_extensions == result) { + cached_extensions = strdup(result); + } + } + const char *filtered = cached_extensions; + pthread_mutex_unlock(&mutex); + + return filtered; +}