formating and listener helper struct

This commit is contained in:
Janis 2022-12-15 19:12:02 +01:00
parent 3da5c0de14
commit afabc727e4

121
main.zig
View file

@ -25,7 +25,6 @@ const Size = struct {
width: u32, width: u32,
height: u32, height: u32,
fn size(self: *Self) usize { fn size(self: *Self) usize {
return self.width * self.height; return self.width * self.height;
} }
@ -88,7 +87,7 @@ fn ListItem(comptime T: type) type {
value: T, value: T,
fn Head() type { fn Head() type {
list.Head(Self, "link"); return list.Head(Self, "link");
} }
fn fromLink(link: *list.Link) *Self { fn fromLink(link: *list.Link) *Self {
@ -164,6 +163,55 @@ const Options = struct {
} }
}; };
const Output = struct {
const Self = @This();
state: *State,
output: *wl.Output,
geometry: Box,
logical_geometry: Box,
scale: i32,
};
/// helper type to handle dynamic dispatch listeners whatever they're called
fn Listener(comptime T: type, comptime D: type) type {
return struct {
const Self = @This();
const Fn = *const fn (obj: *T, event: T.Event, data: *D) void;
data: *D,
callback: Fn,
fn create(data: *D, callback: Fn) Self {
return Self{
.data = data,
.callback = callback,
};
}
fn listener(obj: *T, event: T.Event, self: *Self) void {
return self.callback(obj, event, self.data);
}
fn set(self: *Self, obj: *T) void {
obj.setListener(*Self, listener, self);
}
fn cast(
self: *Self,
comptime D2: type,
new_data: *D2,
new_callback: @TypeOf(Listener(T, D2)).Fn,
) @TypeOf(Listener(T, D2)) {
const other = @ptrCast(Listener(T, D2), self);
other.new_data = new_data;
other.callback = new_callback;
return other;
}
};
}
const State = struct { const State = struct {
const Uninit = struct { const Uninit = struct {
const Self = @This(); const Self = @This();
@ -173,6 +221,8 @@ const State = struct {
dpy: *wl.Display = undefined, dpy: *wl.Display = undefined,
registry: *wl.Registry = undefined, registry: *wl.Registry = undefined,
registry_listener: Listener(wl.Registry, Self) = undefined,
shm: ?*wl.Shm = null, shm: ?*wl.Shm = null,
compositor: ?*wl.Compositor = null, compositor: ?*wl.Compositor = null,
layer_shell: ?*zwlr.LayerShellV1 = null, layer_shell: ?*zwlr.LayerShellV1 = null,
@ -186,13 +236,19 @@ const State = struct {
const self = try ally.create(Self); const self = try ally.create(Self);
const listener = .{
.data = self,
.callback = registryListener,
};
self.* = .{ self.* = .{
.ally = ally, .ally = ally,
.dpy = dpy, .dpy = dpy,
.registry = registry, .registry = registry,
.registry_listener = listener,
}; };
registry.setListener(*Self, registryListener, self); self.registry_listener.set(self.registry);
if (dpy.roundtrip() != .SUCCESS) return error.RoundtripFailed; if (dpy.roundtrip() != .SUCCESS) return error.RoundtripFailed;
return self; return self;
@ -203,21 +259,29 @@ const State = struct {
} }
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, self: *Self) void { fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, self: *Self) void {
switch (event) { switch (event) {
.global => |global| { .global => |global| {
if (std.cstr.cmp(global.interface, wl.Compositor.getInterface().name) == 0) { std.debug.print("global: {s}\n", .{global.interface});
self.compositor = registry.bind(global.name, wl.Compositor, 4) catch return;
} else if (std.cstr.cmp(global.interface, wl.Shm.getInterface().name) == 0) { if (std.cstr.cmp(global.interface, wl.Compositor.getInterface().name) == 0) {
self.shm = registry.bind(global.name, wl.Shm, 1) catch return; self.compositor = registry.bind(global.name, wl.Compositor, 4) catch return;
} else if (std.cstr.cmp(global.interface, zwlr.LayerShellV1.getInterface().name) == 0) { } else if (std.cstr.cmp(global.interface, wl.Shm.getInterface().name) == 0) {
self.layer_shell = registry.bind(global.name, zwlr.LayerShellV1, 1) catch return; self.shm = registry.bind(global.name, wl.Shm, 1) catch return;
} else if (std.cstr.cmp(global.interface, zxdg.OutputManagerV1.getInterface().name) == 0) { } else if (std.cstr.cmp(global.interface, zwlr.LayerShellV1.getInterface().name) == 0) {
self.xdg_output_manager = registry.bind(global.name, zxdg.OutputManagerV1, 2) catch self.layer_shell = registry.bind(global.name, zwlr.LayerShellV1, 1) catch return;
return; } else if (std.cstr.cmp(global.interface, zxdg.OutputManagerV1.getInterface().name) == 0) {
} self.xdg_output_manager = registry.bind(global.name, zxdg.OutputManagerV1, 2) catch
}, return;
.global_remove => {}, } else if (std.cstr.cmp(global.interface, wl.Seat.getInterface().name) == 0) {
} const seat = registry.bind(global.name, wl.Seat, 1) catch return;
_ = seat;
} else if (std.cstr.cmp(global.interface, wl.Output.getInterface().name) == 0) {
const output = registry.bind(global.name, wl.Output, 3) catch return;
_ = output;
}
},
.global_remove => {},
}
} }
fn intoInit(self: *Self) !*Init { fn intoInit(self: *Self) !*Init {
@ -242,14 +306,10 @@ const State = struct {
const cursor_size = std.fmt.parseInt(u32, buf, 10) catch return error.InvalidXCursorSize; const cursor_size = std.fmt.parseInt(u32, buf, 10) catch return error.InvalidXCursorSize;
// i hope this is fine but appears to be requried to reset the listener on the registry init.* = Init{
self.registry.destroy();
const registry = try self.dpy.getRegistry();
init.* = Init {
.ally = self.ally, .ally = self.ally,
.dpy = self.dpy, .dpy = self.dpy,
.registry = registry, .registry = self.registry,
// these 4 fields are set by the registry listener so they may be null at this point // these 4 fields are set by the registry listener so they may be null at this point
// treat that as a hard error tho. // treat that as a hard error tho.
@ -264,7 +324,10 @@ const State = struct {
.cursor_size = cursor_size, .cursor_size = cursor_size,
}; };
init.registry.setListener(*Init, Init.registryListener, init); init.outputs.init();
// i hope this is fine but appears to be requried to reset the listener on the registry
init.registry_listener = self.registry_listener.cast(Init, init, Init.registryListener);
return init; return init;
} }
@ -278,6 +341,8 @@ const State = struct {
dpy: *wl.Display = undefined, dpy: *wl.Display = undefined,
registry: *wl.Registry = undefined, registry: *wl.Registry = undefined,
registry_listener: Listener(wl.Registry, Self) = undefined,
shm: *wl.Shm = undefined, shm: *wl.Shm = undefined,
compositor: *wl.Compositor = undefined, compositor: *wl.Compositor = undefined,
layer_shell: *zwlr.LayerShellV1 = undefined, layer_shell: *zwlr.LayerShellV1 = undefined,
@ -285,6 +350,8 @@ const State = struct {
xkb_context: *xkb.xkb_context = undefined, xkb_context: *xkb.xkb_context = undefined,
outputs: ListItem(Output).Head() = undefined,
cursor_theme: []const u8 = undefined, cursor_theme: []const u8 = undefined,
cursor_size: u32 = undefined, cursor_size: u32 = undefined,
@ -294,8 +361,7 @@ const State = struct {
std.debug.print("registryListener called after init", .{}); std.debug.print("registryListener called after init", .{});
switch (event) { switch (event) {
.global => {}, .global => {},
.global_remove => { .global_remove => {},
},
} }
} }
@ -314,7 +380,6 @@ const State = struct {
}; };
}; };
pub fn main() !void { pub fn main() !void {
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
std.debug.print("All your {s} are belong to us.\n", .{"codebase"}); std.debug.print("All your {s} are belong to us.\n", .{"codebase"});