@@ -1,106 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user