diff --git a/src/RemoteLua.zig b/src/RemoteLua.zig new file mode 100644 index 0000000..cc3a992 --- /dev/null +++ b/src/RemoteLua.zig @@ -0,0 +1,55 @@ +const RemoteLua = @This(); + +const std = @import("std"); +const wayland = @import("wayland"); +const Utils = @import("utils.zig"); +const wl = wayland.server.wl; +const mez = wayland.server.zmez; + +const gpa = std.heap.c_allocator; +const server = &@import("main.zig").server; +const Lua = &@import("main.zig").lua; + +id: usize, +remote_lua_v1: *mez.RemoteLuaV1, + +pub fn sendNewLogEntry(str: [*:0]const u8) void { + for (server.remote_lua_clients.items) |c| { + c.remote_lua_v1.sendNewLogEntry(str); + } +} + +pub fn create(client: *wl.Client, version: u32, id: u32) !void { + const remote_lua_v1 = try mez.RemoteLuaV1.create(client, version, id); + + const node = try gpa.create(RemoteLua); + errdefer gpa.destroy(node); + node = .{ + .remote_lua_v1 = remote_lua_v1, + .id = server.remote_lua_clients.items.len, + }; + server.remote_lua_clients.append(gpa, node); + + remote_lua_v1.setHandler(*RemoteLua, handleRequest, handleDestroy, &node); +} + +fn handleRequest( +remote_lua_v1: *mez.RemoteLuaV1, +request: mez.RemoteLuaV1.Request, +_: *RemoteLua, +) void { + switch (request) { + .destroy => remote_lua_v1.destroy(), + .push_lua => |req| { + Lua.state.loadString(req.lua_chunk) catch { + const errTxt: []const u8 = Lua.state.toString(-1) catch unreachable; + try sendNewLogEntry("repl: " ++ errTxt); + }; + }, + } +} + +fn handleDestroy(_: *mez.RemoteLuaV1, remote_lua: *RemoteLua) void { + server.remote_lua_clients.swapRemove(remote_lua.id); + gpa.destroy(remote_lua); +} diff --git a/src/RemoteLuaManager.zig b/src/RemoteLuaManager.zig new file mode 100644 index 0000000..1df4411 --- /dev/null +++ b/src/RemoteLuaManager.zig @@ -0,0 +1,49 @@ +const RemoteLuaManager = @This(); + +const std = @import("std"); +const wayland = @import("wayland"); +const Utils = @import("utils.zig"); +const RemoteLua = @import("RemoteLua.zig"); +const wl = wayland.server.wl; +const mez = wayland.server.zmez; + +const gpa = std.heap.c_allocator; +const server = &@import("main.zig").server; + +global: *wl.Global, + +pub fn init() ?*RemoteLuaManager { + const self = try gpa.create(RemoteLuaManager); + + self.global = try wl.Global.create(server.wl_server, mez.RemoteLuaManagerV1, 1, ?*anyopaque, null, bind); + + return self; +} + +fn bind(client: *wl.Client, _: ?*anyopaque, version: u32, id: u32) void { + const remote_lua_manager_v1 = mez.RemoteLuaManagerV1.create(client, version, id) catch { + client.postNoMemory(); + Utils.oomPanic(); + }; + remote_lua_manager_v1.setHandler(?*anyopaque, handleRequest, null, null); +} + +fn handleRequest( +remote_lua_manager_v1: *mez.RemoteLuaManagerV1, +request: mez.RemoteLuaManagerV1.Request, +_: ?*anyopaque, +) void { + switch (request) { + .destroy => remote_lua_manager_v1.destroy(), + .get_remote => |req| { + RemoteLua.create( + remote_lua_manager_v1.getClient(), + remote_lua_manager_v1.getVersion(), + req.id, + ) catch { + remote_lua_manager_v1.getClient().postNoMemory(); + Utils.oomPanic(); + }; + }, + } +} diff --git a/src/server.zig b/src/server.zig index d42d8b9..e04c8ad 100644 --- a/src/server.zig +++ b/src/server.zig @@ -14,6 +14,7 @@ const Utils = @import("utils.zig"); const Keymap = @import("types/keymap.zig"); const Hook = @import("types/hook.zig"); const Events = @import("types/events.zig"); +const RemoteLua = @import("RemoteLua.zig"); const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; @@ -41,6 +42,7 @@ cursor: Cursor, keymaps: std.AutoHashMap(u64, Keymap), hooks: std.ArrayList(*Hook), events: Events, +remote_lua_clients: std.ArrayList(*RemoteLua), // Backend listeners new_input: wl.Listener(*wlr.InputDevice) = .init(handleNewInput), @@ -98,6 +100,7 @@ pub fn init(self: *Server) void { .keymaps = .init(gpa), .hooks = try .initCapacity(gpa, 10), // TODO: choose how many slots to start with .events = try .init(gpa), + .remote_lua_clients = try .initCapacity(gpa, 0), }; self.renderer.initServer(wl_server) catch { @@ -132,6 +135,8 @@ pub fn deinit(self: *Server) noreturn { self.new_xdg_popup.link.remove(); self.new_xdg_toplevel_decoration.link.remove(); + self.remote_lua_clients.deinit(gpa); + self.seat.deinit(); self.root.deinit(); self.cursor.deinit(); diff --git a/src/types/hook.zig b/src/types/hook.zig index 511e84a..044a8cd 100644 --- a/src/types/hook.zig +++ b/src/types/hook.zig @@ -7,6 +7,7 @@ const xkb = @import("xkbcommon"); const wlr = @import("wlroots"); const zlua = @import("zlua"); +const RemoteLua = @import("../RemoteLua.zig"); const Event = @import("events.zig"); const Lua = &@import("../main.zig").lua; @@ -38,6 +39,8 @@ pub fn callback(self: *const Hook, args: anytype) void { i = k; } - Lua.state.protectedCall(.{ .args = i }) catch { }; + Lua.state.protectedCall(.{ .args = i }) catch { + RemoteLua.sendNewLogEntry(Lua.state.toString(-1) catch unreachable); + }; Lua.state.pop(-1); }