Skip to content

Commit

Permalink
Latest zig + epoll iterator (#67)
Browse files Browse the repository at this point in the history
# Description

- Elm-architecture-inspired event iterator
- The previous version populated the epoll event data with a pointer.
This pointer was a function pointer to an implementation of a wayland
message handler. When processing messages / events this then happens in
a relatively hidden fashion. Particularly code navigation will be
hampered and the code generally harder to understand.
- This change replaces the function pointer dispatch with a data /
iterator approach. When we have activity on some subsystem(s) epoll will
wake up and return an event iterator. Each call to `.next()` will return
a new event (or null). We will exhaust all events for a given subsystem
before moving onto another subsystem that has activity.
- We exchange a function call (with the function pointers) with
returning a data structure for each event.
    - Those events are then dispatched by `switch`ing on the event.
- In this way we end up with a very straightforward dispatch method that
is very explicit in the code and easy to reason about / navigate over.
- Resource allocation has been reworked.
- Previously resources (clients, window, regions, etc.) were statically
allocated.
- This has been replaced with `IterablePool` and `SubsetPool`. These
allocate on startup but not thereafter.
- The wayland protocol implementation is completely rewritten to provide
way better type safety with an explicit `union` of wayland objects and
messages.
- The protocol generator has been rewritten in zig (using
https://github.com/mitchellh/zig-build-libxml2 for XML parsing) so that
we can jettison the `python` dependency. The generator is currently at
https://github.com/malcolmstill/foxwhale-gen. I think I'll move the
generator code into this repo, but will wait for
mitchellh/zig-build-libxml2#3 so I don't have to
vendor to include the changes in that PR

# Closes
- Closes #59
- Closes #58
- Closes #44
- Closes #11

# Follow ups

- Reimplement DRM/KMS backend
  • Loading branch information
malcolmstill authored Mar 13, 2024
1 parent 51b7057 commit f4c5b8e
Show file tree
Hide file tree
Showing 82 changed files with 14,079 additions and 10,500 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: foxwren tests
name: foxwhale tests
on: push
jobs:
test:
Expand All @@ -10,15 +10,16 @@ jobs:
- uses: actions/checkout@v2
- uses: goto-bus-stop/setup-zig@v1
with:
version: 0.9.1
version: master
- run: sudo apt-get update
- run: sudo apt-get install libglfw3 libglfw3-dev libsystemd-dev libudev-dev libinput-dev libdrm-dev libxkbcommon-dev
- run: sudo apt-get install libx11-dev libxcb1-dev libx11-xcb-dev libegl-dev libgles-dev libsystemd-dev libudev-dev libinput-dev libdrm-dev libgbm-dev libxkbcommon-dev libxkbcommon-x11-dev
- run: zig build
# - run: zig build -fstage1 (stage 1 doesn't support packed struct(u32))
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: goto-bus-stop/setup-zig@v1
with:
version: 0.9.1
version: master
- run: zig fmt --check src/*.zig
21 changes: 0 additions & 21 deletions Makefile

This file was deleted.

3 changes: 0 additions & 3 deletions TOUR.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ in terms of this repo).
- `src/foxwhalectl/`: implementation of a command-line tool for inspecting and debugging
the state of the compositor. It implements `fw_control.xml`.

- `generator/`: this director contains code for generating `protocols.zig` from Wayland XML
files. Ostensibly this is also written in zig, but it is actually hacked together in python.

- `procotols/`: contains custom protocols. The only custom protocol that currently exists
is `fw_control.xml`. This provides a protocol implement both by the compositor and
`foxwhalectl` that allows inspecting compositor state (for debugging purposes) but
Expand Down
58 changes: 44 additions & 14 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const Builder = @import("std").build.Builder;
const std = @import("std");

pub fn build(b: *Builder) void {
pub fn build(b: *std.Build) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
Expand All @@ -10,26 +9,31 @@ pub fn build(b: *Builder) void {

// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const optimize = b.standardOptimizeOption(.{});

const exe = b.addExecutable(.{
.name = "foxwhale",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
.single_threaded = true,
});

const exe = b.addExecutable("foxwhale", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.linkSystemLibrary("c");
exe.linkSystemLibrary("glfw3");
exe.linkSystemLibrary("gl");
exe.linkSystemLibrary("xkbcommon");
// exe.linkSystemLibrary("xkbcommon-x11");
exe.linkSystemLibrary("libsystemd");
exe.linkSystemLibrary("libudev");
exe.linkSystemLibrary("libinput");
exe.linkSystemLibrary("libdrm");
exe.linkSystemLibrary("gbm");
exe.linkSystemLibrary("egl");
if (mode != .Debug) {
exe.strip = true;
}
exe.single_threaded = true;
exe.install();
exe.linkSystemLibrary("xcb");
exe.linkSystemLibrary("X11");
exe.linkSystemLibrary("X11-xcb");

b.installArtifact(exe);

// FIXME: fix client generation of protocols
// const foxwhalectl_exe = b.addExecutable("foxwhalectl", "src/foxwhalectl/main.zig");
Expand All @@ -41,11 +45,37 @@ pub fn build(b: *Builder) void {
// foxwhalectl_exe.single_threaded = true;
// foxwhalectl_exe.install();
// foxwhalectl_exe.addPackagePath("epoll", "src/epoll.zig");
// foxwhalectl_exe.addPackagePath("wl", "src/wl/context.zig");
// foxwhalectl_exe.addPackagePath("wl", "src/wl/wire.zig");

const run_cmd = exe.run();
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());

const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);

// Generate
// ===========================
const foxwhale_gen = b.dependency("foxwhale_gen", .{ .target = target, .optimize = optimize });
const foxwhale_gen_exe = foxwhale_gen.artifact("foxwhale-gen");

const output_path = "src/wl/protocols.zig";
const gen_cmd = b.addRunArtifact(foxwhale_gen_exe);
gen_cmd.addArg("server");
gen_cmd.addArg("--input-file");
gen_cmd.addArg("/usr/share/wayland/wayland.xml");
gen_cmd.addArg("--input-file");
gen_cmd.addArg("/usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml");
gen_cmd.addArg("--input-file");
gen_cmd.addArg("/usr/share/wayland-protocols/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml");
gen_cmd.addArg("--input-file");
gen_cmd.addArg("protocols/fw_control.xml");
gen_cmd.addArg("--output-file");
gen_cmd.addArg(output_path);

const gen_step = b.step("generate", "Generate wayland protocols");

const fmt_step = b.addFmt(.{ .paths = &.{output_path} });
fmt_step.step.dependOn(&gen_cmd.step);

gen_step.dependOn(&fmt_step.step);
}
62 changes: 62 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.{
.name = "foxwhale",
// This is a [Semantic Version](https://semver.org/).
// In a future version of Zig it will be used for package deduplication.
.version = "0.0.0",

// This field is optional.
// This is currently advisory only; Zig does not yet do anything
// with this value.
//.minimum_zig_version = "0.11.0",

// This field is optional.
// Each dependency must either provide a `url` and `hash`, or a `path`.
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
// Once all dependencies are fetched, `zig build` no longer requires
// internet connectivity.
.dependencies = .{
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
.foxwhale_gen = .{
// When updating this field to a new URL, be sure to delete the corresponding
// `hash`, otherwise you are communicating that you expect to find the old hash at
// the new URL.
.url = "https://github.com/malcolmstill/foxwhale-gen/archive/21c0f17c7d2258fcdf0819866d4cf4c784f00213.tar.gz",

// This is computed from the file contents of the directory of files that is
// obtained after fetching `url` and applying the inclusion rules given by
// `paths`.
//
// This field is the source of truth; packages do not come from a `url`; they
// come from a `hash`. `url` is just one of many possible mirrors for how to
// obtain a package matching this `hash`.
//
// Uses the [multihash](https://multiformats.io/multihash/) format.
.hash = "122006b5217a03a29dab5ffc6040814e9cf3da85de6553177d72cd00a7d61584634b",

// When this is provided, the package is found in a directory relative to the
// build root. In this case the package's hash is irrelevant and therefore not
// computed. This field and `url` are mutually exclusive.
// .path = "foo",
},
},

// Specifies the set of files and directories that are included in this package.
// Only files and directories listed here are included in the `hash` that
// is computed for this package.
// Paths are relative to the build root. Use the empty string (`""`) to refer to
// the build root itself.
// A directory listed here means that all files within, recursively, are included.
.paths = .{
// This makes *all* files, recursively, included in this package. It is generally
// better to explicitly list the files and directories instead, to insure that
// fetching from tarballs, file system paths, and version control all result
// in the same contents hash.
"",
// For example...
//"build.zig",
//"build.zig.zon",
//"src",
//"LICENSE",
//"README.md",
},
}
5 changes: 0 additions & 5 deletions generator/README.md

This file was deleted.

Loading

0 comments on commit f4c5b8e

Please sign in to comment.