WIP: implementing IPC

This commit is contained in:
Marcius 2024-02-18 20:15:52 +00:00
parent ae9a97deeb
commit fe20f18af3
8 changed files with 101 additions and 20 deletions

View file

@ -1,11 +1,11 @@
const std = @import("std");
const Scanner = @import("wayland").Scanner;
const Scanner = @import("zig-wayland").Scanner;
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const zig_args_mod = b.dependency("zig_args", .{
const zig_args_mod = b.dependency("zig-args", .{
.target = target,
.optimize = optimize,
}).module("args");

View file

@ -5,11 +5,11 @@
.paths = .{""},
.dependencies = .{
.wayland = .{
.@"zig-wayland" = .{
.url = "git+https://git.mzte.de/LordMZTE/zig-wayland#4de9f2d6d5fddae1fbb29e21fd1dae69e646ab7d",
.hash = "1220d6448c277e5c41348aa95ce2ba2fc92a92cb7a9e9783edf0f816cd0260122d31",
},
.zig_args = .{
.@"zig-args" = .{
.url = "git+https://git.mzte.de/mirrors/zig-args.git#89f18a104d9c13763b90e97d6b4ce133da8a3e2b",
.hash = "12203ded54c85878eea7f12744066dcb4397177395ac49a7b2aa365bf6047b623829",
},

View file

@ -21,13 +21,14 @@ pub const Args = union(enum) {};
const help_msg =
\\Aestuarium v{[version]s} - yet another wayland background manager
\\
\\usage: {[a0]s} [options] <commands>
\\
\\Options:
\\ --help, -h Print this help and exit
\\ --json, -j Returns the result in json format
\\
\\
\\Subcommands:
\\ {[a0]s} outputs Lists the monitors currently available
\\ {[a0]s} help Print this help and exit
\\subcommands:
\\ --outputs Lists the monitors currently available
\\ --help Print this help and exit
;
pub fn printHelp(alloc: Allocator) !void {

View file

@ -1,4 +1,8 @@
pub const c = @cImport({
@cInclude("wayland-egl.h"); // required for egl include to work
pub usingnamespace @cImport({
@cInclude("wayland-egl.h");
@cInclude("EGL/egl.h");
@cDefine("GL_GLEXT_PROTOTYPES", "1");
@cInclude("GL/gl.h");
@cInclude("GL/glext.h");
});

37
src/ipc/socket.zig Normal file
View file

@ -0,0 +1,37 @@
const std = @import("std");
const fs = std.fs;
const net = std.net;
const Server = net.StreamServer;
const Allocator = std.mem.Allocator;
const Socket = @This();
pub fn init() !void {
const logger = std.log.scoped(.IPC);
var server = Server.init(.{
.reuse_port = true,
.reuse_address = true,
});
defer server.deinit();
const path = "/tmp/aestuarium/.aestuarium.sock";
fs.makeDirAbsolute("/tmp/aestuarium/") catch |err| switch (err) {
error.PathAlreadyExists => {},
else => return err,
};
fs.deleteFileAbsolute("/tmp/aestuarium/.aestuarium.sock") catch {};
const address = try std.net.Address.initUnix(path);
try server.listen(address);
logger.info("Starting IPC server...", .{});
var buff: [500]u8 = undefined;
while (true) {
const conn = try server.accept();
const bytes = try conn.stream.read(&buff);
_ = bytes; // autofix
}
}

View file

@ -17,7 +17,6 @@ pub fn log(
.warn => "W: ",
.err => "E: ",
};
stdout.writeAll("") catch {};
switch (scope) {
.default => {},

View file

@ -1,9 +1,11 @@
const std = @import("std");
const c = @import("ffi.zig");
const Allocator = std.mem.Allocator;
const zig_args = @import("zig-args");
const args = @import("args.zig");
const Global = @import("globals.zig");
const Output = @import("output.zig");
const ipc = @import("ipc/socket.zig");
const wayland = @import("wayland");
const wl = wayland.client.wl;
@ -57,17 +59,25 @@ pub fn main() !u8 {
return 0;
}
if (opts.options.json) {
try args.printHelp(arena.allocator());
return 1;
}
// TODO check for existing instances of the app running
mainlog.info("Launching app...", .{});
var global = try Global.init(arena.allocator());
try ipc.init();
return 0;
}
fn loop(allocator: Allocator) !u8 {
var global = try Global.init(allocator);
defer global.deinit();
const info = try Output.init(&global);
const surface = try global.compositor.?.createSurface();
const egl_window = try wl.EglWindow.create(surface, @as(c_int, info.available_outputs[0].width), @as(c_int, info.available_outputs[0].height));
errdefer egl_window.destroy();
const layer_surface = try global.layer_shell.?.getLayerSurface(
surface,
@ -88,11 +98,26 @@ pub fn main() !u8 {
layer_surface.setExclusiveZone(-1);
var buff: [10000]u8 = undefined;
const egl_window = try wl.EglWindow.create(surface, @as(c_int, info.available_outputs[0].width), @as(c_int, info.available_outputs[0].height));
errdefer egl_window.destroy();
const egl_dpy = c.eglGetDisplay(@ptrCast(global.display.?)) orelse return error.EGLError;
const egl_image = c.eglCreateImage(global.display.?, c.EGL_NO_CONTEXT, c.EGL_GL_TEXTURE_2D, @ptrCast(&buff), null);
_ = egl_image; // autofix
const egl_surf = c.eglCreateWindowSurface(egl_dpy, null, @ptrCast(egl_window), null);
const resmc = c.eglMakeCurrent(egl_dpy, egl_surf, egl_surf, null);
if (resmc != c.EGL_TRUE) return error.MakeCurrentFail;
surface.attach(@ptrCast(egl_surf), 0, 0);
c.glTextureImage2DEXT(c.GL_2D, 0, c.GL_RGBA, 0, 1920, 1080, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, @ptrCast(&buff));
surface.commit();
while (global.display.?.dispatch() == .SUCCESS) {
//TODO main loop
if (global.display.?.dispatch() != .SUCCESS) return error.DispatchFail;
while (true) {
//todo implement main loop
}
return 0;

View file

@ -16,6 +16,7 @@ const OutputInfo = struct {
y: i32 = 0,
width: i32 = 0,
height: i32 = 0,
wl_output: *wl.Output,
};
const Output = @This();
@ -26,7 +27,9 @@ pub fn init(global: *Global) !Output {
defer info_list.deinit();
for (global.outputs.?.items) |wl_output| {
var info = OutputInfo{};
var info = OutputInfo{
.wl_output = wl_output,
};
const xdg_output = try global.xdg_output_manager.?.getXdgOutput(wl_output);
xdg_output.setListener(*OutputInfo, xdgOutputListener, &info);
if (global.display.?.roundtrip() != .SUCCESS) return error.RoundtripFail;
@ -38,14 +41,14 @@ pub fn init(global: *Global) !Output {
};
}
const Options = struct {
const ListOutputsOptions = struct {
format: enum {
normal,
json,
} = .normal,
};
pub fn listOutputs(self: Output, options: Options) ![][]const u8 {
pub fn listOutputs(self: Output, options: ListOutputsOptions) ![][]const u8 {
switch (options.format) {
.json => {
// TODO return json string
@ -69,6 +72,18 @@ pub fn listOutputs(self: Output, options: Options) ![][]const u8 {
}
}
pub fn findOutputByName(self: Output, name: []const u8) !OutputInfo {
for (self.available_outputs) |output| {
if (std.mem.eql(u8, output.name, name)) return output;
}
return error.NoSuchOutput;
}
pub fn findOutputByLogicalPosition(self: Output) !OutputInfo {
_ = self; // autofix
}
fn xdgOutputListener(_: *zxdg.OutputV1, ev: zxdg.OutputV1.Event, info: *OutputInfo) void {
switch (ev) {
.name => |e| {