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 wayland = @import("root.zig");
const freetype = @import("freetype");
const harfbuzz = @import("harfbuzz");
const font_assets = @import("font-assets");
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;
const width = if (app.state == .run_mobile) app.state.run_mobile.width else app.state.run_desktop.width;
const height = if (app.state == .run_mobile) app.state.run_mobile.height else app.state.run_desktop.height;
std.debug.assert(app.state == .run);
const pool = &app.state.run.pool;
const width = app.state.run.width;
const height = app.state.run.height;
// render
const canvas = try pool.getFramebuffer(.{ width, height });
@ -183,18 +185,13 @@ const App = struct {
keyboard: ?wayland.core.Keyboard = null,
touch: ?wayland.core.Touch = null,
},
run_mobile: struct {
width: u32,
height: u32,
pool: Pool,
touch: wayland.core.Touch,
},
run_desktop: struct {
run: struct {
width: u32,
height: u32,
pool: Pool,
keyboard: wayland.core.Keyboard,
pointer: wayland.core.Pointer,
pointer: ?wayland.core.Pointer = null,
touch: ?wayland.core.Touch = null,
mouse: struct {
x: f32,
y: f32,
@ -214,6 +211,12 @@ const App = struct {
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 {
std.debug.assert(app.state == .init);
const init = app.state.init;
@ -223,34 +226,26 @@ const App = struct {
app.callbacks.clearRetainingCapacity();
try app.callbacks.put(app.display.id, displayHandler);
if (init.touch != null and init.keyboard == null) {
// 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,
.height = init.toplevel_config.?.height,
.pool = try Pool.init(app.ally, app.shm),
.keyboard = init.keyboard.?,
.pointer = init.pointer.?,
.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.xdg_surface.id, surfaceDesktopHandler);
try app.callbacks.put(app.xdg_wmbase.id, wmbaseHandler);
try app.callbacks.put(app.xdg_toplevel.id, toplevelHandler);
} else {
@panic("no keyboard or touch");
app.state = .{ .run = .{
.width = init.toplevel_config.?.width,
.height = init.toplevel_config.?.height,
.pool = try Pool.init(app.ally, app.shm),
.keyboard = init.keyboard.?,
.mouse = .{ .x = 0, .y = 0 },
} };
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_wmbase.id, wmbaseHandler);
try app.callbacks.put(app.xdg_toplevel.id, toplevelHandler);
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 {
fd: std.os.fd_t,
shm: wayland.core.ShmPool,
mem: []u8,
mem: []align(4096) u8,
file_length: usize,
allocationTable: std.AutoHashMap(u32, Buffer),
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 {
var iter = pool.allocationTable.iterator();
var first_offset: usize = std.math.maxInt(usize);
@ -467,14 +468,28 @@ const Canvas = struct {
const row = fb[y * width .. (y + 1) * width];
for (left..right, 0..) |x, a| {
const pixel = &row[x];
const intensity = buffer[i * cols + a];
const intensity: u16 = buffer[i * cols + a];
if (intensity != 0) {
pixel.* = .{
intensity,
intensity,
intensity,
@intCast(intensity),
@intCast(intensity),
@intCast(intensity),
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;
height = 128;
}
if (app.state == .run_mobile) {
app.state.run_mobile.width = @intCast(width);
app.state.run_mobile.height = @intCast(height);
} else {
app.state.run_desktop.width = @intCast(width);
app.state.run_desktop.height = @intCast(height);
}
std.debug.assert(app.state == .run);
app.state.run.width = @intCast(width);
app.state.run.height = @intCast(height);
},
.close => {
app.close();
},
else => {
std.log.info("toplevel event: {}", .{event});
@ -535,9 +549,11 @@ fn surfaceDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !
switch (event) {
.configure => |conf| {
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;
const height = if (app.state == .run_mobile) app.state.run_mobile.height else app.state.run_desktop.height;
std.debug.assert(app.state == .run);
const pool = &app.state.run.pool;
const width = app.state.run.width;
const height = app.state.run.height;
// render
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);
switch (event) {
.enter => |enter| {
app.state.run_desktop.mouse.x = @floatFromInt(enter.surface_x);
app.state.run_desktop.mouse.y = @floatFromInt(enter.surface_y);
app.state.run.mouse.x = @floatFromInt(enter.surface_x);
app.state.run.mouse.y = @floatFromInt(enter.surface_y);
},
.leave => |_| {},
.motion => |motion| {
app.state.run_desktop.mouse.x = @floatFromInt(motion.surface_x);
app.state.run_desktop.mouse.y = @floatFromInt(motion.surface_y);
app.state.run.mouse.x = @floatFromInt(motion.surface_x);
app.state.run.mouse.y = @floatFromInt(motion.surface_y);
},
else => {
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);
_ = app;
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 {
const event = try wayland.deserialize(wayland.core.Buffer.Event, header, body);
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);
}