aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2020-03-23 01:21:15 +0100
committerIsaac Freund <ifreund@ifreund.xyz>2020-03-23 01:21:15 +0100
commitf423f5317bfa46fe8a7a0149240ea5fe49bd5f89 (patch)
tree1919def7562a5d8d224f31e9a2d88024e09d1bd2
parent0584fde12625832d16a600a0900641cbb9a8b1c8 (diff)
downloadriver-f423f5317bfa46fe8a7a0149240ea5fe49bd5f89.tar.gz
river-f423f5317bfa46fe8a7a0149240ea5fe49bd5f89.tar.xz
Rework Server
-rw-r--r--include/render.c11
-rw-r--r--include/render.h7
-rw-r--r--src/main.zig58
-rw-r--r--src/server.zig102
4 files changed, 87 insertions, 91 deletions
diff --git a/include/render.c b/include/render.c
index 2a85fb7..36e42c3 100644
--- a/include/render.c
+++ b/include/render.c
@@ -2,19 +2,14 @@
#include <wlr/backend.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);
}
-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);
}
-bool zag_wlr_backend_start(struct wlr_backend *backend) {
+bool wlr_backend_start(struct wlr_backend *backend) {
return wlr_backend_start(backend);
}
-
-void zag_wlr_backend_destroy(struct wlr_backend *backend) {
- zag_wlr_backend_destroy(backend);
-}
-
diff --git a/include/render.h b/include/render.h
index cb0bd52..3ac3cf2 100644
--- a/include/render.h
+++ b/include/render.h
@@ -18,10 +18,9 @@ struct wlr_backend {
} events;
};
-struct wlr_backend *zag_wlr_backend_autocreate(struct wl_display *display);
-struct wlr_renderer *zag_wlr_backend_get_renderer(struct wlr_backend *backend);
-bool zag_wlr_backend_start(struct wlr_backend *backend);
-void zag_wlr_backend_destroy(struct wlr_backend *backend);
+struct wlr_backend *wlr_backend_autocreate(struct wl_display *display);
+struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend);
+bool wlr_backend_start(struct wlr_backend *backend);
#endif
diff --git a/src/main.zig b/src/main.zig
index 9034289..76ddf8d 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,31 +1,13 @@
const std = @import("std");
const c = @import("c.zig").c;
-const man_c = @import("c.zig").manual;
-
-const ZagError = error{
- InitError,
- CantAddSocket,
- CantStartBackend,
- CantSetEnv,
-};
pub fn main() !void {
std.debug.warn("Starting up.\n", .{});
c.wlr_log_init(c.enum_wlr_log_importance.WLR_DEBUG, null);
- var server: Server = undefined;
-
- // 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);
+ var server = try Server.init(std.heap.c_allocator);
+ defer server.deinit();
// Set up our list of views and the xdg-shell. The xdg-shell is a Wayland
// protocol which is used for application windows.
@@ -35,39 +17,13 @@ pub fn main() !void {
server.new_xdg_surface.notify = 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.
- const socket = c.wl_display_add_socket_auto(server.wl_display);
- if (socket == null) {
- c.zag_wlr_backend_destroy(server.backend);
- return ZagError.CantAddSocket;
- }
+ try server.start();
- // Start the backend. This will enumerate outputs and inputs, become the DRM
- // master, etc
- if (!c.zag_wlr_backend_start(server.backend)) {
- 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" };
+ // Spawn an instance of alacritty
+ // const argv = [_][]const u8{ "/bin/sh", "-c", "WAYLAND_DEBUG=1 alacritty" };
+ const argv = [_][]const u8{ "/bin/sh", "-c", "alacritty" };
var child = try std.ChildProcess.init(&argv, std.heap.c_allocator);
try std.ChildProcess.spawn(child);
- // Run the Wayland event loop. This does not return until you exit the
- // 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);
+ server.run();
}
diff --git a/src/server.zig b/src/server.zig
index fc1fef0..d1e0002 100644
--- a/src/server.zig
+++ b/src/server.zig
@@ -3,45 +3,92 @@ const c = @import("c.zig").c;
pub const Server = struct {
wl_display: *c.wl_display,
- backend: *c.wlr_backend,
- renderer: *c.wlr_renderer,
+ wlr_backend: *c.wlr_backend,
+ 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,
new_xdg_surface: c.wl_listener,
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() {
- var server: @This() = undefined;
+ var server = undefined;
// The Wayland display is managed by libwayland. It handles accepting
// clients from the Unix socket, manging Wayland globals, and so on.
- server.wl_display = c.wl_display_create() orelse return error.CantCreateWlDisplay;
-
- // The backend is a wlroots feature which abstracts the underlying input and
- // output hardware. The autocreate option will choose the most suitable
- // backend based on the current environment, such as opening an X11 window
- // 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
- // backend uses the renderer, for example, to fall back to software cursors
- // if the backend does not support hardware cursors (some older GPUs
- // don't).
- server.backend = c.zag_wlr_backend_autocreate(server.wl_display) orelse return error.CantCreateWlrBackend;
+ server.wl_display = c.wl_display_create() orelse
+ return error.CantCreateWlDisplay;
+ errdefer c.wl_display_destroy(server.wl_display);
+
+ // The wlr_backend abstracts the input/output hardware. Autocreate chooses
+ // the best option based on the environment, for example DRM when run from
+ // a tty or wayland if WAYLAND_DISPLAY is set.
+ //
+ // This frees itself when the wl_display is destroyed.
+ server.wlr_backend = c.wlr_backend_autocreate(server.wl_display) orelse
+ return error.CantCreateWlrBackend;
// 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
// supports for shared memory, this configures that for clients.
- server.renderer = c.zag_wlr_backend_get_renderer(server.backend) orelse return error.CantGetWlrRenderer;
- c.wlr_renderer_init_wl_display(server.renderer, server.wl_display) orelse return error.CantInitWlDisplay;
-
- // This creates some hands-off wlroots interfaces. The compositor is
- // necessary for clients to allocate surfaces and the data device manager
- // handles the clipboard. Each of these wlroots interfaces has room for you
- // to dig your fingers in and play with their behavior if you want.
- _ = c.wlr_compositor_create(server.wl_display, server.renderer) orelse return error.CantCreateWlrCompositor;
- _ = c.wlr_data_device_manager_create(server.wl_display) orelse return error.CantCreateWlrDataDeviceManager;
+ server.wlr_renderer = c.wlr_backend_get_renderer(server.backend) orelse
+ return error.CantGetWlrRenderer;
+ c.wlr_renderer_init_wl_display(server.wlr_renderer, server.wl_display) orelse
+ return error.CantInitWlDisplay;
+
+ // These both free themselves when the wl_display is destroyed
+ _ = c.wlr_compositor_create(server.wl_display, server.renderer) orelse
+ return error.CantCreateWlrCompositor;
+ _ = 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 {
@@ -67,5 +114,4 @@ pub const Server = struct {
}
return true;
}
-
};