Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-09-30 09:53:53 +03:00
parent e072b1f6e0
commit a253869c24

106
src/egl_override.c Normal file
View File

@@ -0,0 +1,106 @@
#define _GNU_SOURCE
#include <EGL/egl.h>
#include <dlfcn.h>
#include <pthread.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 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;
}