wayland: Phase 32 — display_open/close/screen_count through vtable
Add three display-lifecycle slots to WMBackend:
display_open(name) — open/init display connection, return Display*
(NULL for Wayland; compositor init side-effect)
display_close() — tear down display connection
display_screen_count() — number of logical screens
x11_backend: implement with XOpenDisplay (including close-on-exec fcntl),
XCloseDisplay, ScreenCount(dpy); remove fcntl/FD_CLOEXEC from main.c.
wl_backend: implement display_open() with full wlroots headless compositor
init — wl_display_create, wlr_headless_backend_create, wlr_renderer_autocreate,
wlr_backend_start. display_close() tears down in reverse order.
Compositor state held in a file-static struct. Adds -DWLR_USE_UNSTABLE
to WLROOTS_CFLAGS in configure.ac.
main.c: move backend selection before display_open() (was in StartUp()),
call wm_backend->display_open() instead of XOpenDisplay(); guard all
X11-specific post-open code (visual-id, DisplayName, wXModifierInitialize)
in if(dpy != NULL).
startup.c: replace ScreenCount(dpy) with wm_backend->display_screen_count();
remove now-redundant backend-selection block (owned by main.c).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e8e230b2db
commit
d07362b90e
|
|
@ -671,6 +671,7 @@ AS_IF([test "x$enable_wayland_backend" != "xno"],
|
|||
AS_IF([test "x$have_wlroots" = "xyes"],
|
||||
[AC_DEFINE([USE_WAYLAND_BACKEND], [1],
|
||||
[Define to 1 to build the wlroots Wayland compositor backend])
|
||||
WLROOTS_CFLAGS="$WLROOTS_CFLAGS -DWLR_USE_UNSTABLE"
|
||||
supported_core="$supported_core WaylandBackend"],
|
||||
[AS_IF([test "x$enable_wayland_backend" = "xyes"],
|
||||
[AC_MSG_ERROR([wlroots >= 0.15, wayland-server, or xkbcommon not found])])
|
||||
|
|
|
|||
|
|
@ -46,6 +46,32 @@ struct WObjDescriptor;
|
|||
*/
|
||||
typedef struct WMBackend {
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Display lifecycle (Phase 32) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
/*
|
||||
* Open the display connection and return the native handle.
|
||||
* X11: XOpenDisplay(name) -- returns Display*.
|
||||
* Wayland: initialises the wl_display + wlroots compositor; returns NULL
|
||||
* (no X11 Display* exists in the Wayland path).
|
||||
* Called from main.c before StartUp(). Sets up any connection-level
|
||||
* state (e.g. X11 close-on-exec flag).
|
||||
*/
|
||||
void *(*display_open)(const char *name);
|
||||
|
||||
/*
|
||||
* Close/destroy the display connection.
|
||||
* Called during final shutdown after all screens have been closed.
|
||||
*/
|
||||
void (*display_close)(void);
|
||||
|
||||
/*
|
||||
* Return the number of logical screens (X11: ScreenCount; Wayland: 1).
|
||||
* Called from main.c / StartUp() after display_open().
|
||||
*/
|
||||
int (*display_screen_count)(void);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Screen lifecycle (Phase 2) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
* Phase 31: complete stub vtable. Every slot compiles and returns a safe
|
||||
* zero/null/false value. Subsequent phases will replace stubs with real
|
||||
* wlroots implementations one functional area at a time.
|
||||
* Phase 32: display_open/close/screen_count implemented with wlroots headless
|
||||
* backend.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -12,6 +14,13 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/headless.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "../../WindowMaker.h"
|
||||
#include "../../screen.h"
|
||||
|
|
@ -19,6 +28,92 @@
|
|||
#include "../backend.h"
|
||||
#include "wl_backend.h"
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Global compositor state */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
struct wl_compositor_state {
|
||||
struct wl_display *display;
|
||||
struct wlr_backend *backend;
|
||||
struct wlr_renderer *renderer;
|
||||
int started; /* non-zero after successful display_open */
|
||||
};
|
||||
|
||||
static struct wl_compositor_state wl_state;
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Display lifecycle (Phase 32) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void *
|
||||
wl_display_open(const char *name)
|
||||
{
|
||||
(void)name; /* Wayland compositor picks its own socket name */
|
||||
|
||||
wlr_log_init(WLR_ERROR, NULL);
|
||||
|
||||
wl_state.display = wl_display_create();
|
||||
if (!wl_state.display) {
|
||||
wwarning("wl_backend: failed to create wl_display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_state.backend = wlr_headless_backend_create(wl_state.display);
|
||||
if (!wl_state.backend) {
|
||||
wwarning("wl_backend: failed to create wlroots headless backend");
|
||||
wl_display_destroy(wl_state.display);
|
||||
wl_state.display = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_state.renderer = wlr_renderer_autocreate(wl_state.backend);
|
||||
if (!wl_state.renderer) {
|
||||
wwarning("wl_backend: failed to create wlroots renderer");
|
||||
wlr_backend_destroy(wl_state.backend);
|
||||
wl_display_destroy(wl_state.display);
|
||||
wl_state.backend = NULL;
|
||||
wl_state.display = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!wlr_backend_start(wl_state.backend)) {
|
||||
wwarning("wl_backend: failed to start wlroots headless backend");
|
||||
wlr_renderer_destroy(wl_state.renderer);
|
||||
wlr_backend_destroy(wl_state.backend);
|
||||
wl_display_destroy(wl_state.display);
|
||||
wl_state.renderer = NULL;
|
||||
wl_state.backend = NULL;
|
||||
wl_state.display = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_state.started = 1;
|
||||
return NULL; /* no X11 Display* in the Wayland path */
|
||||
}
|
||||
|
||||
static void
|
||||
wl_display_close(void)
|
||||
{
|
||||
if (!wl_state.started)
|
||||
return;
|
||||
if (wl_state.renderer)
|
||||
wlr_renderer_destroy(wl_state.renderer);
|
||||
if (wl_state.backend)
|
||||
wlr_backend_destroy(wl_state.backend);
|
||||
if (wl_state.display)
|
||||
wl_display_destroy(wl_state.display);
|
||||
wl_state.renderer = NULL;
|
||||
wl_state.backend = NULL;
|
||||
wl_state.display = NULL;
|
||||
wl_state.started = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
wl_display_screen_count(void)
|
||||
{
|
||||
return wl_state.started ? 1 : 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Screen open/close */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -435,6 +530,10 @@ static void wl_register_error_handlers(void) {}
|
|||
/* ------------------------------------------------------------------ */
|
||||
|
||||
const WMBackend wl_backend = {
|
||||
.display_open = wl_display_open,
|
||||
.display_close = wl_display_close,
|
||||
.display_screen_count = wl_display_screen_count,
|
||||
|
||||
.screen_open = wl_screen_open,
|
||||
.screen_close = wl_screen_close,
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
|
@ -70,6 +72,36 @@ struct WBackendScreen {
|
|||
int screen_number; /* X11 screen index */
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Display lifecycle (Phase 32) */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static void *
|
||||
x11_display_open(const char *name)
|
||||
{
|
||||
Display *d = XOpenDisplay(name);
|
||||
if (!d)
|
||||
return NULL;
|
||||
if (fcntl(ConnectionNumber(d), F_SETFD, FD_CLOEXEC) < 0)
|
||||
werror("error setting close-on-exec flag for X connection");
|
||||
return d;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_display_close(void)
|
||||
{
|
||||
if (dpy) {
|
||||
XCloseDisplay(dpy);
|
||||
dpy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
x11_display_screen_count(void)
|
||||
{
|
||||
return dpy ? ScreenCount(dpy) : 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Screen lifecycle */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
@ -2326,6 +2358,9 @@ x11_register_error_handlers(void)
|
|||
/* -------------------------------------------------------------------- */
|
||||
|
||||
const WMBackend x11_backend = {
|
||||
.display_open = x11_display_open,
|
||||
.display_close = x11_display_close,
|
||||
.display_screen_count = x11_display_screen_count,
|
||||
.screen_open = x11_screen_open,
|
||||
.screen_close = x11_screen_close,
|
||||
.frame_create_toplevel = x11_frame_create_toplevel,
|
||||
|
|
|
|||
73
src/main.c
73
src/main.c
|
|
@ -55,6 +55,11 @@
|
|||
#include "main.h"
|
||||
#include "monitor.h"
|
||||
#include "misc.h"
|
||||
#include "backend/backend.h"
|
||||
#include "backend/x11/x11_backend.h"
|
||||
#ifdef USE_WAYLAND_BACKEND
|
||||
#include "backend/wayland/wl_backend.h"
|
||||
#endif
|
||||
|
||||
#include <WINGs/WUtil.h>
|
||||
|
||||
|
|
@ -765,44 +770,48 @@ static int real_main(int argc, char **argv)
|
|||
*ptr = 0;
|
||||
}
|
||||
|
||||
/* Select backend before opening the display. */
|
||||
#ifdef USE_WAYLAND_BACKEND
|
||||
if (getenv("WMAKER_USE_WAYLAND"))
|
||||
wm_backend = &wl_backend;
|
||||
else
|
||||
#endif
|
||||
wm_backend = &x11_backend;
|
||||
|
||||
/* open display */
|
||||
dpy = XOpenDisplay(DisplayName);
|
||||
if (dpy == NULL) {
|
||||
dpy = (Display *)wm_backend->display_open(DisplayName);
|
||||
if (dpy == NULL && wm_backend == &x11_backend) {
|
||||
wfatal(_("could not open display \"%s\""), XDisplayName(DisplayName));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fcntl(ConnectionNumber(dpy), F_SETFD, FD_CLOEXEC) < 0) {
|
||||
werror("error setting close-on-exec flag for X connection");
|
||||
exit(1);
|
||||
if (dpy != NULL) {
|
||||
if (getWVisualID(0) < 0) {
|
||||
/*
|
||||
* If unspecified, use default visual instead of waiting
|
||||
* for wrlib/context.c:bestContext() that may end up choosing
|
||||
* the "fake" 24 bits added by the Composite extension.
|
||||
* This is required to avoid all sort of corruptions when
|
||||
* composite is enabled, and at a depth other than 24.
|
||||
*/
|
||||
setWVisualID(0, (int)DefaultVisual(dpy, DefaultScreen(dpy))->visualid);
|
||||
}
|
||||
|
||||
/* check if the user specified a complete display name (with screen).
|
||||
* If so, only manage the specified screen */
|
||||
if (DisplayName)
|
||||
pos = strchr(DisplayName, ':');
|
||||
else
|
||||
pos = NULL;
|
||||
|
||||
if (pos && sscanf(pos, ":%i.%i", &d, &s) == 2)
|
||||
multiHead = False;
|
||||
|
||||
DisplayName = XDisplayName(DisplayName);
|
||||
setenv("DISPLAY", DisplayName, 1);
|
||||
|
||||
wXModifierInitialize();
|
||||
}
|
||||
|
||||
|
||||
if (getWVisualID(0) < 0) {
|
||||
/*
|
||||
* If unspecified, use default visual instead of waiting
|
||||
* for wrlib/context.c:bestContext() that may end up choosing
|
||||
* the "fake" 24 bits added by the Composite extension.
|
||||
* This is required to avoid all sort of corruptions when
|
||||
* composite is enabled, and at a depth other than 24.
|
||||
*/
|
||||
setWVisualID(0, (int)DefaultVisual(dpy, DefaultScreen(dpy))->visualid);
|
||||
}
|
||||
|
||||
/* check if the user specified a complete display name (with screen).
|
||||
* If so, only manage the specified screen */
|
||||
if (DisplayName)
|
||||
pos = strchr(DisplayName, ':');
|
||||
else
|
||||
pos = NULL;
|
||||
|
||||
if (pos && sscanf(pos, ":%i.%i", &d, &s) == 2)
|
||||
multiHead = False;
|
||||
|
||||
DisplayName = XDisplayName(DisplayName);
|
||||
setenv("DISPLAY", DisplayName, 1);
|
||||
|
||||
wXModifierInitialize();
|
||||
StartUp(!multiHead);
|
||||
|
||||
if (w_global.screen_count == 1)
|
||||
|
|
|
|||
|
|
@ -49,9 +49,6 @@
|
|||
#include "session.h"
|
||||
#include "defaults.h"
|
||||
#include "backend/x11/x11_backend.h"
|
||||
#ifdef USE_WAYLAND_BACKEND
|
||||
#include "backend/wayland/wl_backend.h"
|
||||
#endif
|
||||
#include "properties.h"
|
||||
#include "dialog.h"
|
||||
#include "wmspec.h"
|
||||
|
|
@ -516,19 +513,13 @@ void StartUp(Bool defaultScreenOnly)
|
|||
if (defaultScreenOnly)
|
||||
max = 1;
|
||||
else
|
||||
max = ScreenCount(dpy);
|
||||
max = wm_backend->display_screen_count();
|
||||
|
||||
wScreen = wmalloc(sizeof(WScreen *) * max);
|
||||
|
||||
w_global.screen_count = 0;
|
||||
|
||||
/* Select the display backend before any screen is initialized. */
|
||||
#ifdef USE_WAYLAND_BACKEND
|
||||
if (getenv("WMAKER_USE_WAYLAND"))
|
||||
wm_backend = &wl_backend;
|
||||
else
|
||||
#endif
|
||||
wm_backend = &x11_backend;
|
||||
/* wm_backend is selected in real_main() before display_open(). */
|
||||
|
||||
/* Check if TIFF images are supported */
|
||||
formats = RSupportedFileFormats();
|
||||
|
|
|
|||
Loading…
Reference in New Issue