From bad25c409cfe9c15fdacdc0ebc203480cf1733f5 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Sat, 16 Jan 2021 20:29:54 +1100 Subject: [PATCH] [client] displayserver: add new `earlyInit` to the interface Some platforms such as Wayland need to set environment vairables before SDL is initialized, as such this change detects the display server before SDL has started and calls the new `earlyInit` method providing the implementation an opportunity to set things up. --- client/displayservers/SDL/sdl.c | 6 ++ client/include/interface/displayserver.h | 5 +- client/src/main.c | 83 ++++++++++++------------ 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/client/displayservers/SDL/sdl.c b/client/displayservers/SDL/sdl.c index 91fac034..a79013b6 100644 --- a/client/displayservers/SDL/sdl.c +++ b/client/displayservers/SDL/sdl.c @@ -33,6 +33,11 @@ struct SDLDSState static struct SDLDSState sdl; +static bool sdlEarlyInit(void) +{ + return true; +} + static void sdlInit(SDL_SysWMinfo * info) { memset(&sdl, 0, sizeof(sdl)); @@ -143,6 +148,7 @@ static void sdlWarpMouse(int x, int y, bool exiting) struct LG_DisplayServerOps LGDS_SDL = { .subsystem = SDL_SYSWM_UNKNOWN, + .earlyInit = sdlEarlyInit, .init = sdlInit, .startup = sdlStartup, .shutdown = sdlShutdown, diff --git a/client/include/interface/displayserver.h b/client/include/interface/displayserver.h index 28b5abde..7146cc7d 100644 --- a/client/include/interface/displayserver.h +++ b/client/include/interface/displayserver.h @@ -49,7 +49,10 @@ struct LG_DisplayServerOps { const SDL_SYSWM_TYPE subsystem; - /* early initialization */ + /* called before SDL has been initialized */ + bool (*earlyInit)(void); + + /* called after SDL has been initialized */ void (*init)(SDL_SysWMinfo * info); /* called at startup after window creation, renderer and/or SPICE is ready */ diff --git a/client/src/main.c b/client/src/main.c index f22bcfc9..3c4beaf8 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -1654,19 +1654,48 @@ static int lg_run(void) if (g_cursor.sens < -9) g_cursor.sens = -9; else if (g_cursor.sens > 9) g_cursor.sens = 9; - if (getenv("WAYLAND_DISPLAY")) + + // try to early detect the platform + SDL_SYSWM_TYPE subsystem = SDL_SYSWM_UNKNOWN; + if (getenv("WAYLAND_DISPLAY")) subsystem = SDL_SYSWM_WAYLAND; + else if (getenv("DISPLAY" )) subsystem = SDL_SYSWM_X11; + else + DEBUG_WARN("Unknown subsystem, falling back to SDL default"); + + // search for the best displayserver ops to use + for(int i = 0; i < LG_DISPLAYSERVER_COUNT; ++i) + if (LG_DisplayServers[i]->subsystem == subsystem) + { + g_state.ds = LG_DisplayServers[i]; + break; + } + + assert(g_state.ds); + + // set any null methods to the fallback +#define SET_FALLBACK(x) \ + if (!g_state.ds->x) g_state.ds->x = LG_DisplayServers[0]->x; + SET_FALLBACK(earlyInit); + SET_FALLBACK(getProp); + SET_FALLBACK(init); + SET_FALLBACK(startup); + SET_FALLBACK(shutdown); + SET_FALLBACK(free); + SET_FALLBACK(eventFilter); + SET_FALLBACK(grabPointer); + SET_FALLBACK(ungrabKeyboard); + SET_FALLBACK(warpMouse); + SET_FALLBACK(cbInit); + SET_FALLBACK(cbNotice); + SET_FALLBACK(cbRelease); + SET_FALLBACK(cbRequest); +#undef SET_FALLBACK + + // init the subsystem + if (!g_state.ds->earlyInit()) { - DEBUG_INFO("Wayland detected"); - if (getenv("SDL_VIDEODRIVER") == NULL) - { - int err = setenv("SDL_VIDEODRIVER", "wayland", 1); - if (err < 0) - { - DEBUG_ERROR("Unable to set the env variable SDL_VIDEODRIVER: %d", err); - return -1; - } - DEBUG_INFO("SDL_VIDEODRIVER has been set to wayland"); - } + DEBUG_ERROR("Subsystem early init failed"); + return -1; } if (!params.noScreensaver) @@ -1793,36 +1822,6 @@ static int lg_run(void) return -1; } - // search for the best displayserver ops to use - for(int i = 0; i < LG_DISPLAYSERVER_COUNT; ++i) - if (LG_DisplayServers[i]->subsystem == g_state.wminfo.subsystem) - { - g_state.ds = LG_DisplayServers[i]; - break; - } - - if (!g_state.ds) - g_state.ds = LG_DisplayServers[0]; - - // set any null methods to the fallback -#define SET_FALLBACK(x) \ - if (!g_state.ds->x) g_state.ds->x = LG_DisplayServers[0]->x; - SET_FALLBACK(getProp); - SET_FALLBACK(init); - SET_FALLBACK(startup); - SET_FALLBACK(shutdown); - SET_FALLBACK(free); - SET_FALLBACK(eventFilter); - SET_FALLBACK(grabPointer); - SET_FALLBACK(ungrabKeyboard); - SET_FALLBACK(warpMouse); - SET_FALLBACK(cbInit); - SET_FALLBACK(cbNotice); - SET_FALLBACK(cbRelease); - SET_FALLBACK(cbRequest); -#undef SET_FALLBACK - - // init the subsystem g_state.ds->init(&g_state.wminfo); SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,