Rework Server
This commit is contained in:
parent
0584fde126
commit
f423f5317b
@ -2,19 +2,14 @@
|
|||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
|
|
||||||
struct wlr_backend *zag_wlr_backend_autocreate(struct wl_display *display) {
|
struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
|
||||||
return wlr_backend_autocreate(display, NULL);
|
return wlr_backend_autocreate(display, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_renderer *zag_wlr_backend_get_renderer(struct wlr_backend *backend) {
|
struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend) {
|
||||||
return wlr_backend_get_renderer(backend);
|
return wlr_backend_get_renderer(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zag_wlr_backend_start(struct wlr_backend *backend) {
|
bool wlr_backend_start(struct wlr_backend *backend) {
|
||||||
return wlr_backend_start(backend);
|
return wlr_backend_start(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zag_wlr_backend_destroy(struct wlr_backend *backend) {
|
|
||||||
zag_wlr_backend_destroy(backend);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -18,10 +18,9 @@ struct wlr_backend {
|
|||||||
} events;
|
} events;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_backend *zag_wlr_backend_autocreate(struct wl_display *display);
|
struct wlr_backend *wlr_backend_autocreate(struct wl_display *display);
|
||||||
struct wlr_renderer *zag_wlr_backend_get_renderer(struct wlr_backend *backend);
|
struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend);
|
||||||
bool zag_wlr_backend_start(struct wlr_backend *backend);
|
bool wlr_backend_start(struct wlr_backend *backend);
|
||||||
void zag_wlr_backend_destroy(struct wlr_backend *backend);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
58
src/main.zig
58
src/main.zig
@ -1,31 +1,13 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const c = @import("c.zig").c;
|
const c = @import("c.zig").c;
|
||||||
const man_c = @import("c.zig").manual;
|
|
||||||
|
|
||||||
const ZagError = error{
|
|
||||||
InitError,
|
|
||||||
CantAddSocket,
|
|
||||||
CantStartBackend,
|
|
||||||
CantSetEnv,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
std.debug.warn("Starting up.\n", .{});
|
std.debug.warn("Starting up.\n", .{});
|
||||||
|
|
||||||
c.wlr_log_init(c.enum_wlr_log_importance.WLR_DEBUG, null);
|
c.wlr_log_init(c.enum_wlr_log_importance.WLR_DEBUG, null);
|
||||||
|
|
||||||
var server: Server = undefined;
|
var server = try Server.init(std.heap.c_allocator);
|
||||||
|
defer server.deinit();
|
||||||
// Creates an output layout, which a wlroots utility for working with an
|
|
||||||
// arrangement of screens in a physical layout.
|
|
||||||
server.output_layout = c.wlr_output_layout_create();
|
|
||||||
|
|
||||||
server.outputs = std.ArrayList(Output).init(std.heap.c_allocator);
|
|
||||||
|
|
||||||
// Configure a listener to be notified when new outputs are available on the
|
|
||||||
// backend.
|
|
||||||
server.new_output.notify = server_new_output;
|
|
||||||
c.wl_signal_add(&server.backend.*.events.new_output, &server.new_output);
|
|
||||||
|
|
||||||
// Set up our list of views and the xdg-shell. The xdg-shell is a Wayland
|
// Set up our list of views and the xdg-shell. The xdg-shell is a Wayland
|
||||||
// protocol which is used for application windows.
|
// protocol which is used for application windows.
|
||||||
@ -35,39 +17,13 @@ pub fn main() !void {
|
|||||||
server.new_xdg_surface.notify = server_new_xdg_surface;
|
server.new_xdg_surface.notify = server_new_xdg_surface;
|
||||||
c.wl_signal_add(&server.xdg_shell.*.events.new_surface, &server.new_xdg_surface);
|
c.wl_signal_add(&server.xdg_shell.*.events.new_surface, &server.new_xdg_surface);
|
||||||
|
|
||||||
// Add a Unix socket to the Wayland display.
|
try server.start();
|
||||||
const socket = c.wl_display_add_socket_auto(server.wl_display);
|
|
||||||
if (socket == null) {
|
|
||||||
c.zag_wlr_backend_destroy(server.backend);
|
|
||||||
return ZagError.CantAddSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the backend. This will enumerate outputs and inputs, become the DRM
|
// Spawn an instance of alacritty
|
||||||
// master, etc
|
// const argv = [_][]const u8{ "/bin/sh", "-c", "WAYLAND_DEBUG=1 alacritty" };
|
||||||
if (!c.zag_wlr_backend_start(server.backend)) {
|
const argv = [_][]const u8{ "/bin/sh", "-c", "alacritty" };
|
||||||
c.zag_wlr_backend_destroy(server.backend);
|
|
||||||
c.wl_display_destroy(server.wl_display);
|
|
||||||
return ZagError.CantStartBackend;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the WAYLAND_DISPLAY environment variable to our socket and run the
|
|
||||||
// startup command if requested. */
|
|
||||||
if (c.setenv("WAYLAND_DISPLAY", socket, 1) == -1) {
|
|
||||||
return ZagError.CantSetEnv;
|
|
||||||
}
|
|
||||||
|
|
||||||
const argv = [_][]const u8{ "/bin/sh", "-c", "WAYLAND_DEBUG=1 alacritty" };
|
|
||||||
var child = try std.ChildProcess.init(&argv, std.heap.c_allocator);
|
var child = try std.ChildProcess.init(&argv, std.heap.c_allocator);
|
||||||
try std.ChildProcess.spawn(child);
|
try std.ChildProcess.spawn(child);
|
||||||
|
|
||||||
// Run the Wayland event loop. This does not return until you exit the
|
server.run();
|
||||||
// compositor. Starting the backend rigged up all of the necessary event
|
|
||||||
// loop configuration to listen to libinput events, DRM events, generate
|
|
||||||
// frame events at the refresh rate, and so on.
|
|
||||||
//c.wlr_log(WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
|
|
||||||
c.wl_display_run(server.wl_display);
|
|
||||||
|
|
||||||
// Once wl_display_run returns, we shut down the server.
|
|
||||||
c.wl_display_destroy_clients(server.wl_display);
|
|
||||||
c.wl_display_destroy(server.wl_display);
|
|
||||||
}
|
}
|
||||||
|
@ -3,45 +3,92 @@ const c = @import("c.zig").c;
|
|||||||
|
|
||||||
pub const Server = struct {
|
pub const Server = struct {
|
||||||
wl_display: *c.wl_display,
|
wl_display: *c.wl_display,
|
||||||
backend: *c.wlr_backend,
|
wlr_backend: *c.wlr_backend,
|
||||||
renderer: *c.wlr_renderer,
|
wlr_renderer: *c.wlr_renderer,
|
||||||
|
|
||||||
|
wlr_output_layout: *c.wlr_output_layout,
|
||||||
|
outputs: std.ArrayList(Output),
|
||||||
|
|
||||||
|
listen_new_output: c.wl_listener,
|
||||||
|
|
||||||
xdg_shell: *c.wlr_xdg_shell,
|
xdg_shell: *c.wlr_xdg_shell,
|
||||||
new_xdg_surface: c.wl_listener,
|
new_xdg_surface: c.wl_listener,
|
||||||
views: std.ArrayList(View),
|
views: std.ArrayList(View),
|
||||||
|
|
||||||
output_layout: *c.wlr_output_layout,
|
|
||||||
outputs: std.ArrayList(Output),
|
|
||||||
new_output: c.wl_listener,
|
|
||||||
|
|
||||||
pub fn init(allocator: *std.mem.Allocator) !@This() {
|
pub fn init(allocator: *std.mem.Allocator) !@This() {
|
||||||
var server: @This() = undefined;
|
var server = undefined;
|
||||||
|
|
||||||
// The Wayland display is managed by libwayland. It handles accepting
|
// The Wayland display is managed by libwayland. It handles accepting
|
||||||
// clients from the Unix socket, manging Wayland globals, and so on.
|
// clients from the Unix socket, manging Wayland globals, and so on.
|
||||||
server.wl_display = c.wl_display_create() orelse return error.CantCreateWlDisplay;
|
server.wl_display = c.wl_display_create() orelse
|
||||||
|
return error.CantCreateWlDisplay;
|
||||||
|
errdefer c.wl_display_destroy(server.wl_display);
|
||||||
|
|
||||||
// The backend is a wlroots feature which abstracts the underlying input and
|
// The wlr_backend abstracts the input/output hardware. Autocreate chooses
|
||||||
// output hardware. The autocreate option will choose the most suitable
|
// the best option based on the environment, for example DRM when run from
|
||||||
// backend based on the current environment, such as opening an X11 window
|
// a tty or wayland if WAYLAND_DISPLAY is set.
|
||||||
// if an X11 server is running. The NULL argument here optionally allows you
|
//
|
||||||
// to pass in a custom renderer if wlr_renderer doesn't meet your needs. The
|
// This frees itself when the wl_display is destroyed.
|
||||||
// backend uses the renderer, for example, to fall back to software cursors
|
server.wlr_backend = c.wlr_backend_autocreate(server.wl_display) orelse
|
||||||
// if the backend does not support hardware cursors (some older GPUs
|
return error.CantCreateWlrBackend;
|
||||||
// don't).
|
|
||||||
server.backend = c.zag_wlr_backend_autocreate(server.wl_display) orelse return error.CantCreateWlrBackend;
|
|
||||||
|
|
||||||
// If we don't provide a renderer, autocreate makes a GLES2 renderer for us.
|
// If we don't provide a renderer, autocreate makes a GLES2 renderer for us.
|
||||||
// The renderer is responsible for defining the various pixel formats it
|
// The renderer is responsible for defining the various pixel formats it
|
||||||
// supports for shared memory, this configures that for clients.
|
// supports for shared memory, this configures that for clients.
|
||||||
server.renderer = c.zag_wlr_backend_get_renderer(server.backend) orelse return error.CantGetWlrRenderer;
|
server.wlr_renderer = c.wlr_backend_get_renderer(server.backend) orelse
|
||||||
c.wlr_renderer_init_wl_display(server.renderer, server.wl_display) orelse return error.CantInitWlDisplay;
|
return error.CantGetWlrRenderer;
|
||||||
|
c.wlr_renderer_init_wl_display(server.wlr_renderer, server.wl_display) orelse
|
||||||
|
return error.CantInitWlDisplay;
|
||||||
|
|
||||||
// This creates some hands-off wlroots interfaces. The compositor is
|
// These both free themselves when the wl_display is destroyed
|
||||||
// necessary for clients to allocate surfaces and the data device manager
|
_ = c.wlr_compositor_create(server.wl_display, server.renderer) orelse
|
||||||
// handles the clipboard. Each of these wlroots interfaces has room for you
|
return error.CantCreateWlrCompositor;
|
||||||
// to dig your fingers in and play with their behavior if you want.
|
_ = c.wlr_data_device_manager_create(server.wl_display) orelse
|
||||||
_ = c.wlr_compositor_create(server.wl_display, server.renderer) orelse return error.CantCreateWlrCompositor;
|
return error.CantCreateWlrDataDeviceManager;
|
||||||
_ = c.wlr_data_device_manager_create(server.wl_display) orelse return error.CantCreateWlrDataDeviceManager;
|
|
||||||
|
// Create an output layout, which a wlroots utility for working with an
|
||||||
|
// arrangement of screens in a physical layout.
|
||||||
|
server.wlr_output_layout = c.wlr_output_layout_create() orelse
|
||||||
|
return error.CantCreateWlrOutputLayout;
|
||||||
|
errdefer c.wlr_output_layout_destroy(server.wlr_output_layout);
|
||||||
|
|
||||||
|
server.outputs = std.ArrayList(Output).init(std.heap.c_allocator);
|
||||||
|
|
||||||
|
// Setup a listener for new outputs
|
||||||
|
server.listen_new_output = handle_new_output;
|
||||||
|
c.wl_signal_add(&server.wlr_backend.*.events.new_output, &server.listen_new_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free allocated memory and clean up
|
||||||
|
pub fn deinit(self: @This()) void {
|
||||||
|
c.wl_display_destroy_clients(self.wl_display);
|
||||||
|
c.wl_display_destroy(self.wl_display);
|
||||||
|
c.wlr_output_layout_destroy(self.wlr_output_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create the socket, set WAYLAND_DISPLAY, and start the backend
|
||||||
|
pub fn start(self: @This()) !void {
|
||||||
|
// Add a Unix socket to the Wayland display.
|
||||||
|
const socket = c.wl_display_add_socket_auto(self.wl_display) orelse;
|
||||||
|
return error.CantAddSocket;
|
||||||
|
|
||||||
|
// Start the backend. This will enumerate outputs and inputs, become the DRM
|
||||||
|
// master, etc
|
||||||
|
if (!c.wlr_backend_start(self.wlr_backend)) {
|
||||||
|
c.wlr_backend_destroy(self.wlr_backend);
|
||||||
|
return error.CantStartBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the WAYLAND_DISPLAY environment variable to our socket and run the
|
||||||
|
// startup command if requested. */
|
||||||
|
if (c.setenv("WAYLAND_DISPLAY", socket, 1) == -1) {
|
||||||
|
return error.CantSetEnv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enter the wayland event loop and block until the compositor is exited
|
||||||
|
pub fn run(self: @This()) void {
|
||||||
|
c.wl_display_run(server.wl_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_keybinding(self: *@This(), sym: c.xkb_keysym_t) bool {
|
pub fn handle_keybinding(self: *@This(), sym: c.xkb_keysym_t) bool {
|
||||||
@ -67,5 +114,4 @@ pub const Server = struct {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user