[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.
This commit is contained in:
Geoffrey McRae 2021-01-16 20:29:54 +11:00
parent ef678bab1d
commit bad25c409c
3 changed files with 51 additions and 43 deletions

View File

@ -33,6 +33,11 @@ struct SDLDSState
static struct SDLDSState sdl; static struct SDLDSState sdl;
static bool sdlEarlyInit(void)
{
return true;
}
static void sdlInit(SDL_SysWMinfo * info) static void sdlInit(SDL_SysWMinfo * info)
{ {
memset(&sdl, 0, sizeof(sdl)); memset(&sdl, 0, sizeof(sdl));
@ -143,6 +148,7 @@ static void sdlWarpMouse(int x, int y, bool exiting)
struct LG_DisplayServerOps LGDS_SDL = struct LG_DisplayServerOps LGDS_SDL =
{ {
.subsystem = SDL_SYSWM_UNKNOWN, .subsystem = SDL_SYSWM_UNKNOWN,
.earlyInit = sdlEarlyInit,
.init = sdlInit, .init = sdlInit,
.startup = sdlStartup, .startup = sdlStartup,
.shutdown = sdlShutdown, .shutdown = sdlShutdown,

View File

@ -49,7 +49,10 @@ struct LG_DisplayServerOps
{ {
const SDL_SYSWM_TYPE subsystem; 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); void (*init)(SDL_SysWMinfo * info);
/* called at startup after window creation, renderer and/or SPICE is ready */ /* called at startup after window creation, renderer and/or SPICE is ready */

View File

@ -1654,20 +1654,49 @@ static int lg_run(void)
if (g_cursor.sens < -9) g_cursor.sens = -9; if (g_cursor.sens < -9) g_cursor.sens = -9;
else 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)
{ {
DEBUG_INFO("Wayland detected"); g_state.ds = LG_DisplayServers[i];
if (getenv("SDL_VIDEODRIVER") == NULL) 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())
{ {
int err = setenv("SDL_VIDEODRIVER", "wayland", 1); DEBUG_ERROR("Subsystem early init failed");
if (err < 0)
{
DEBUG_ERROR("Unable to set the env variable SDL_VIDEODRIVER: %d", err);
return -1; return -1;
} }
DEBUG_INFO("SDL_VIDEODRIVER has been set to wayland");
}
}
if (!params.noScreensaver) if (!params.noScreensaver)
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
@ -1793,36 +1822,6 @@ static int lg_run(void)
return -1; 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); g_state.ds->init(&g_state.wminfo);
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,