feat: remove mobile<->desktop split

dev
Louis Pearson 2024-02-17 13:36:39 -07:00
parent 051f0b7ffb
commit 008d1b48ef
1 changed files with 87 additions and 61 deletions

View File

@ -1,6 +1,7 @@
const std = @import("std"); const std = @import("std");
const wayland = @import("root.zig"); const wayland = @import("root.zig");
const freetype = @import("freetype"); const freetype = @import("freetype");
const harfbuzz = @import("harfbuzz");
const font_assets = @import("font-assets"); const font_assets = @import("font-assets");
const Conn = wayland.Conn; const Conn = wayland.Conn;
@ -129,9 +130,10 @@ pub fn main() !void {
} }
} }
const pool = if (app.state == .run_mobile) &app.state.run_mobile.pool else &app.state.run_desktop.pool; std.debug.assert(app.state == .run);
const width = if (app.state == .run_mobile) app.state.run_mobile.width else app.state.run_desktop.width; const pool = &app.state.run.pool;
const height = if (app.state == .run_mobile) app.state.run_mobile.height else app.state.run_desktop.height; const width = app.state.run.width;
const height = app.state.run.height;
// render // render
const canvas = try pool.getFramebuffer(.{ width, height }); const canvas = try pool.getFramebuffer(.{ width, height });
@ -183,18 +185,13 @@ const App = struct {
keyboard: ?wayland.core.Keyboard = null, keyboard: ?wayland.core.Keyboard = null,
touch: ?wayland.core.Touch = null, touch: ?wayland.core.Touch = null,
}, },
run_mobile: struct { run: struct {
width: u32,
height: u32,
pool: Pool,
touch: wayland.core.Touch,
},
run_desktop: struct {
width: u32, width: u32,
height: u32, height: u32,
pool: Pool, pool: Pool,
keyboard: wayland.core.Keyboard, keyboard: wayland.core.Keyboard,
pointer: wayland.core.Pointer, pointer: ?wayland.core.Pointer = null,
touch: ?wayland.core.Touch = null,
mouse: struct { mouse: struct {
x: f32, x: f32,
y: f32, y: f32,
@ -214,6 +211,12 @@ const App = struct {
app.callbacks.deinit(); app.callbacks.deinit();
} }
fn close(app: *App) void {
std.debug.assert(app.state == .run);
app.state.run.pool.deinit();
app.state = .close;
}
fn checkInit(app: *App) !void { fn checkInit(app: *App) !void {
std.debug.assert(app.state == .init); std.debug.assert(app.state == .init);
const init = app.state.init; const init = app.state.init;
@ -223,34 +226,26 @@ const App = struct {
app.callbacks.clearRetainingCapacity(); app.callbacks.clearRetainingCapacity();
try app.callbacks.put(app.display.id, displayHandler); try app.callbacks.put(app.display.id, displayHandler);
if (init.touch != null and init.keyboard == null) { app.state = .{ .run = .{
// mobile
app.state = .{ .run_mobile = .{
.width = init.toplevel_config.?.width,
.height = init.toplevel_config.?.height,
.pool = try Pool.init(app.ally, app.shm),
.touch = init.touch.?,
} };
try app.callbacks.put(app.xdg_wmbase.id, wmbaseHandler);
try app.callbacks.put(app.xdg_toplevel.id, toplevelHandler);
// try app.callbacks.put(app.state.run_desktop.touch.id, touchMobileHandler);
} else if (init.keyboard != null and init.pointer != null) {
// desktop
app.state = .{ .run_desktop = .{
.width = init.toplevel_config.?.width, .width = init.toplevel_config.?.width,
.height = init.toplevel_config.?.height, .height = init.toplevel_config.?.height,
.pool = try Pool.init(app.ally, app.shm), .pool = try Pool.init(app.ally, app.shm),
.keyboard = init.keyboard.?, .keyboard = init.keyboard.?,
.pointer = init.pointer.?,
.mouse = .{ .x = 0, .y = 0 }, .mouse = .{ .x = 0, .y = 0 },
} }; } };
try app.callbacks.put(app.state.run_desktop.pointer.id, pointerDesktopHandler);
try app.callbacks.put(app.state.run_desktop.keyboard.id, keyboardDesktopHandler); try app.callbacks.put(app.state.run.keyboard.id, keyboardHandler);
try app.callbacks.put(app.xdg_surface.id, surfaceDesktopHandler); try app.callbacks.put(app.xdg_surface.id, surfaceDesktopHandler);
try app.callbacks.put(app.xdg_wmbase.id, wmbaseHandler); try app.callbacks.put(app.xdg_wmbase.id, wmbaseHandler);
try app.callbacks.put(app.xdg_toplevel.id, toplevelHandler); try app.callbacks.put(app.xdg_toplevel.id, toplevelHandler);
} else {
@panic("no keyboard or touch"); if (init.touch) |touch| {
app.state.run.touch = touch;
try app.callbacks.put(touch.id, touchHandler);
}
if (init.pointer) |pointer| {
app.state.run.pointer = pointer;
try app.callbacks.put(pointer.id, pointerHandler);
} }
} }
}; };
@ -328,7 +323,7 @@ fn displayHandler(app: *App, header: wayland.Header, body: []const u32) !void {
const Pool = struct { const Pool = struct {
fd: std.os.fd_t, fd: std.os.fd_t,
shm: wayland.core.ShmPool, shm: wayland.core.ShmPool,
mem: []u8, mem: []align(4096) u8,
file_length: usize, file_length: usize,
allocationTable: std.AutoHashMap(u32, Buffer), allocationTable: std.AutoHashMap(u32, Buffer),
const Buffer = struct { const Buffer = struct {
@ -365,6 +360,12 @@ const Pool = struct {
}; };
} }
pub fn deinit(pool: *Pool) void {
pool.allocationTable.deinit();
std.os.munmap(pool.mem);
std.os.close(pool.fd);
}
fn getFramebuffer(pool: *Pool, size: [2]u32) !Canvas { fn getFramebuffer(pool: *Pool, size: [2]u32) !Canvas {
var iter = pool.allocationTable.iterator(); var iter = pool.allocationTable.iterator();
var first_offset: usize = std.math.maxInt(usize); var first_offset: usize = std.math.maxInt(usize);
@ -467,14 +468,28 @@ const Canvas = struct {
const row = fb[y * width .. (y + 1) * width]; const row = fb[y * width .. (y + 1) * width];
for (left..right, 0..) |x, a| { for (left..right, 0..) |x, a| {
const pixel = &row[x]; const pixel = &row[x];
const intensity = buffer[i * cols + a]; const intensity: u16 = buffer[i * cols + a];
if (intensity != 0) { if (intensity != 0) {
pixel.* = .{ pixel.* = .{
intensity, @intCast(intensity),
intensity, @intCast(intensity),
intensity, @intCast(intensity),
0xFF, 0xFF,
}; };
// TODO: properly implement blending
// const over_alpha = intensity;
// const under_alpha = pixel[3];
// const blended_alpha = over_alpha +| under_alpha *| (255 -| over_alpha);
// const color1: u16 = intensity * over_alpha + pixel[0] *| under_alpha *| (255 -| over_alpha);
// const color2: u16 = intensity * over_alpha + pixel[1] *| under_alpha *| (255 -| over_alpha);
// const color3: u16 = intensity * over_alpha + pixel[2] *| under_alpha *| (255 -| over_alpha);
// pixel.* = .{
// @intCast(color1 / 255),
// @intCast(color2 / 255),
// @intCast(color3 / 255),
// @intCast(blended_alpha / 255),
// };
} }
} }
} }
@ -516,13 +531,12 @@ fn toplevelHandler(app: *App, header: wayland.Header, body: []const u32) !void {
width = 128; width = 128;
height = 128; height = 128;
} }
if (app.state == .run_mobile) { std.debug.assert(app.state == .run);
app.state.run_mobile.width = @intCast(width); app.state.run.width = @intCast(width);
app.state.run_mobile.height = @intCast(height); app.state.run.height = @intCast(height);
} else { },
app.state.run_desktop.width = @intCast(width); .close => {
app.state.run_desktop.height = @intCast(height); app.close();
}
}, },
else => { else => {
std.log.info("toplevel event: {}", .{event}); std.log.info("toplevel event: {}", .{event});
@ -535,9 +549,11 @@ fn surfaceDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !
switch (event) { switch (event) {
.configure => |conf| { .configure => |conf| {
try app.xdg_surface.ack_configure(conf.serial); try app.xdg_surface.ack_configure(conf.serial);
const pool = if (app.state == .run_mobile) &app.state.run_mobile.pool else &app.state.run_desktop.pool;
const width = if (app.state == .run_mobile) app.state.run_mobile.width else app.state.run_desktop.width; std.debug.assert(app.state == .run);
const height = if (app.state == .run_mobile) app.state.run_mobile.height else app.state.run_desktop.height; const pool = &app.state.run.pool;
const width = app.state.run.width;
const height = app.state.run.height;
// render // render
const canvas = try pool.getFramebuffer(.{ width, height }); const canvas = try pool.getFramebuffer(.{ width, height });
@ -549,17 +565,27 @@ fn surfaceDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !
} }
} }
fn pointerDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !void { fn touchHandler(app: *App, header: wayland.Header, body: []const u32) !void {
const event = try wayland.deserialize(wayland.core.Touch.Event, header, body);
_ = app;
switch (event) {
else => {
std.log.info("touch event: {}", .{event});
},
}
}
fn pointerHandler(app: *App, header: wayland.Header, body: []const u32) !void {
const event = try wayland.deserialize(wayland.core.Pointer.Event, header, body); const event = try wayland.deserialize(wayland.core.Pointer.Event, header, body);
switch (event) { switch (event) {
.enter => |enter| { .enter => |enter| {
app.state.run_desktop.mouse.x = @floatFromInt(enter.surface_x); app.state.run.mouse.x = @floatFromInt(enter.surface_x);
app.state.run_desktop.mouse.y = @floatFromInt(enter.surface_y); app.state.run.mouse.y = @floatFromInt(enter.surface_y);
}, },
.leave => |_| {}, .leave => |_| {},
.motion => |motion| { .motion => |motion| {
app.state.run_desktop.mouse.x = @floatFromInt(motion.surface_x); app.state.run.mouse.x = @floatFromInt(motion.surface_x);
app.state.run_desktop.mouse.y = @floatFromInt(motion.surface_y); app.state.run.mouse.y = @floatFromInt(motion.surface_y);
}, },
else => { else => {
std.log.info("pointer event: {}", .{event}); std.log.info("pointer event: {}", .{event});
@ -575,7 +601,7 @@ fn pointerDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !
} }
} }
fn keyboardDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !void { fn keyboardHandler(app: *App, header: wayland.Header, body: []const u32) !void {
const event = try wayland.deserialize(wayland.core.Keyboard.Event, header, body); const event = try wayland.deserialize(wayland.core.Keyboard.Event, header, body);
_ = app; _ = app;
switch (event) { switch (event) {
@ -596,6 +622,6 @@ fn keyboardDesktopHandler(app: *App, header: wayland.Header, body: []const u32)
fn bufferHandler(app: *App, header: wayland.Header, body: []const u32) !void { fn bufferHandler(app: *App, header: wayland.Header, body: []const u32) !void {
const event = try wayland.deserialize(wayland.core.Buffer.Event, header, body); const event = try wayland.deserialize(wayland.core.Buffer.Event, header, body);
std.debug.assert(event == .release); std.debug.assert(event == .release);
const pool = if (app.state == .run_mobile) &app.state.run_mobile.pool else &app.state.run_desktop.pool; const pool = &app.state.run.pool;
try pool.freeFramebuffer(header.object_id); try pool.freeFramebuffer(header.object_id);
} }