Wallpickr compatibility with Aestuarium newest version
This commit is contained in:
parent
26a5e526b5
commit
7e432b59e2
8 changed files with 179 additions and 62 deletions
|
@ -1,20 +1,3 @@
|
|||
# Aestuarium
|
||||
|
||||
Yet another wayland background manager using openGL. This is still in very early stages of development and I don't recommend anyone to use it yet.
|
||||
|
||||
### Why another tool for background in wayland?
|
||||
|
||||
Because all other tools for background didn't have the features I want and also nothing bad in some competition
|
||||
|
||||
### Why the name "Aestuarium"
|
||||
|
||||
It is the latin for [Estuary](https://en.wikipedia.org/wiki/Estuary), I will leave the explanation to your imagination.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- [zigimg/zigimg](https://github.com/zigimg/zigimg)
|
||||
- [getty-zig/json](https://github.com/getty-zig/json)
|
||||
- [ifeund/zig-wayland](https://codeberg.org/ifreund/zig-wayland)
|
||||
- [ziglibs/known-folders](https://github.com/ziglibs/known-folders)
|
||||
- [ziglibs/ini](https://github.com/ziglibs/ini)
|
||||
- [MasterQ32/zig-args](https://github.com/MasterQ32/zig-args)
|
||||
Well, at the moment this is a complet copy of the original project but I plan to later on make some changes here
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const std = @import("std");
|
||||
const Outputs = @import("Outputs.zig");
|
||||
const Render = @import("Render.zig");
|
||||
const Preload = @import("Preload.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
|
@ -18,6 +19,7 @@ layer_shell: ?*zwlr.LayerShellV1 = null,
|
|||
xdg_output_manager: ?*zxdg.OutputManagerV1 = null,
|
||||
outputs_info: ?Outputs = null,
|
||||
rendered_outputs: ?[]*Render = null,
|
||||
preloaded: ?*Preload = null,
|
||||
|
||||
const Globals = @This();
|
||||
|
||||
|
@ -127,7 +129,7 @@ fn registryListener(registry: *wl.Registry, ev: wl.Registry.Event, data: *Global
|
|||
|
||||
.global_remove => |remove_event| {
|
||||
//TODO handle output removed
|
||||
std.log.warn("Global Removed {}", .{remove_event.name});
|
||||
std.log.warn("Global Removed {}", .{remove_event});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
91
scripts/aestuarium/src/Preload.zig
Normal file
91
scripts/aestuarium/src/Preload.zig
Normal file
|
@ -0,0 +1,91 @@
|
|||
const std = @import("std");
|
||||
const zigimg = @import("zigimg");
|
||||
const c = @import("ffi.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Image = zigimg.Image;
|
||||
|
||||
const Preload = @This();
|
||||
|
||||
alloc: Allocator,
|
||||
preloaded_list: std.ArrayList(*Preloaded),
|
||||
|
||||
const Preloaded = struct {
|
||||
index: usize,
|
||||
path: []const u8,
|
||||
height: c_int,
|
||||
width: c_int,
|
||||
bytes: []const u8,
|
||||
format: c_int,
|
||||
zigimg: *Image,
|
||||
};
|
||||
|
||||
pub fn init(alloc: Allocator) Preload {
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
.preloaded_list = std.ArrayList(*Preloaded).init(alloc),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn preload(self: *Preload, path: []const u8) !void {
|
||||
if (self.findPreloaded(path) != null) {
|
||||
std.log.warn("Already preloaded", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
var image = try zigimg.Image.fromFilePath(self.alloc, path);
|
||||
|
||||
var preloaded = try self.alloc.create(Preloaded);
|
||||
|
||||
std.debug.print("to preload: {s}", .{path});
|
||||
const new_mem_path = try self.alloc.alloc(u8, path.len);
|
||||
@memcpy(new_mem_path, path);
|
||||
preloaded.path = new_mem_path;
|
||||
preloaded.bytes = image.rawBytes();
|
||||
preloaded.height = @intCast(image.height);
|
||||
preloaded.width = @intCast(image.width);
|
||||
preloaded.zigimg = ℑ
|
||||
|
||||
preloaded.format = try switch (image.pixelFormat()) {
|
||||
.rgba32, .rgba64 => c.GL_RGBA,
|
||||
.rgb24, .rgb48, .rgb565, .rgb555 => c.GL_RGB,
|
||||
.bgr24, .bgr555 => c.GL_BGR,
|
||||
.bgra32 => c.GL_BGRA,
|
||||
else => error.FormatUnsuported,
|
||||
};
|
||||
|
||||
try self.preloaded_list.append(preloaded);
|
||||
|
||||
preloaded.index = self.preloaded_list.items.len - 1;
|
||||
}
|
||||
|
||||
pub fn findPreloaded(self: Preload, path: []const u8) ?*Preloaded {
|
||||
for (self.preloaded_list.items) |preloaded| {
|
||||
if (std.mem.eql(u8, preloaded.path, path)) {
|
||||
return preloaded;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn unload(self: *Preload, path: []const u8) void {
|
||||
if (std.mem.eql(u8, "all", path)) {
|
||||
self.preloaded_list.deinit();
|
||||
self.preloaded_list = std.ArrayList(*Preloaded).init(self.alloc);
|
||||
return;
|
||||
}
|
||||
if (self.findPreloaded(path)) |preloaded| {
|
||||
preloaded.zigimg.deinit();
|
||||
self.alloc.destroy(preloaded);
|
||||
_ = self.preloaded_list.orderedRemove(preloaded.index);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Preload) void {
|
||||
for (self.preloaded_list.items) |preloaded| {
|
||||
preloaded.zigimg.deinit();
|
||||
self.alloc.free(preloaded.path);
|
||||
self.alloc.destroy(preloaded);
|
||||
}
|
||||
self.preloaded_list.deinit();
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
const std = @import("std");
|
||||
const c = @import("ffi.zig");
|
||||
const wayland = @import("wayland");
|
||||
const zigimg = @import("zigimg");
|
||||
|
||||
const Globals = @import("Globals.zig");
|
||||
const OutputInfo = @import("Outputs.zig").OutputInfo;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const zigimg = @import("zigimg");
|
||||
const Image = zigimg.Image;
|
||||
const Preload = @import("Preload.zig");
|
||||
|
||||
const wayland = @import("wayland");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Image = zigimg.Image;
|
||||
const wl = wayland.client.wl;
|
||||
const zxdg = wayland.client.zxdg;
|
||||
const zwlr = wayland.client.zwlr;
|
||||
|
@ -21,6 +23,7 @@ egl_context: c.EGLContext,
|
|||
egl_window: *wl.EglWindow,
|
||||
egl_surface: c.EGLSurface,
|
||||
output_info: OutputInfo,
|
||||
preload: *Preload,
|
||||
|
||||
pub fn init(
|
||||
alloc: Allocator,
|
||||
|
@ -28,6 +31,7 @@ pub fn init(
|
|||
display: *wl.Display,
|
||||
layer_shell: ?*zwlr.LayerShellV1,
|
||||
output_info: OutputInfo,
|
||||
preload: *Preload,
|
||||
) !Render {
|
||||
const surface = try compositor.?.createSurface();
|
||||
|
||||
|
@ -119,23 +123,12 @@ pub fn init(
|
|||
.layer = layer_surface,
|
||||
.surface = surface,
|
||||
.output_info = output_info,
|
||||
.preload = preload,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setWallpaper(self: *Render, path: []const u8) !void {
|
||||
var image = try zigimg.Image.fromFilePath(self.allocator, path);
|
||||
defer image.deinit();
|
||||
|
||||
//only support RGB AND RGBA yet
|
||||
const image_format: c_int = try switch (image.pixelFormat()) {
|
||||
.rgba32, .rgba64 => c.GL_RGBA,
|
||||
.rgb24, .rgb48, .rgb565, .rgb555 => c.GL_RGB,
|
||||
else => error.FormatUnsuported,
|
||||
};
|
||||
|
||||
const width: c_int = @intCast(image.width);
|
||||
const height: c_int = @intCast(image.height);
|
||||
const texture = image.rawBytes();
|
||||
const preloaded = self.preload.findPreloaded(path) orelse return error.ImageNotPreloaded;
|
||||
|
||||
// Vertex Shader
|
||||
const vertexShaderSource = @embedFile("shaders/main_vertex_shader.glsl");
|
||||
|
@ -253,13 +246,13 @@ pub fn setWallpaper(self: *Render, path: []const u8) !void {
|
|||
c.glTexImage2D(
|
||||
c.GL_TEXTURE_2D,
|
||||
0,
|
||||
image_format,
|
||||
width,
|
||||
height,
|
||||
preloaded.format,
|
||||
preloaded.width,
|
||||
preloaded.height,
|
||||
0,
|
||||
@intCast(image_format),
|
||||
@intCast(preloaded.format),
|
||||
c.GL_UNSIGNED_BYTE,
|
||||
texture.ptr,
|
||||
preloaded.bytes.ptr,
|
||||
);
|
||||
|
||||
c.glGenerateMipmap(c.GL_TEXTURE_2D);
|
||||
|
@ -269,7 +262,6 @@ pub fn setWallpaper(self: *Render, path: []const u8) !void {
|
|||
|
||||
c.glDrawElements(c.GL_TRIANGLES, 6, c.GL_UNSIGNED_BYTE, @ptrFromInt(0));
|
||||
|
||||
try getEglError();
|
||||
try getEglError();
|
||||
// swap double-buffered framebuffer
|
||||
if (c.eglSwapBuffers(self.egl_display, self.egl_surface) != c.EGL_TRUE) return error.EGLError;
|
||||
|
|
|
@ -8,14 +8,10 @@ const Outputs = @import("Outputs.zig");
|
|||
const Config = @import("Config.zig");
|
||||
const Render = @import("Render.zig");
|
||||
const Server = @import("socket/Server.zig");
|
||||
const Preload = @import("Preload.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const wayland = @import("wayland");
|
||||
const wl = wayland.client.wl;
|
||||
const zxdg = wayland.client.zxdg;
|
||||
const zwlr = wayland.client.zwlr;
|
||||
|
||||
pub const std_options = .{
|
||||
.logFn = @import("log.zig").log,
|
||||
.log_level = .debug,
|
||||
|
@ -87,19 +83,27 @@ fn runMainInstance(alloc: Allocator) !u8 {
|
|||
var rendered_outputs = std.ArrayList(*Render).init(alloc);
|
||||
defer rendered_outputs.deinit();
|
||||
|
||||
var preload = Preload.init(alloc);
|
||||
defer preload.deinit();
|
||||
|
||||
globals.preloaded = &preload;
|
||||
|
||||
for (config.monitor_wallpapers) |mw| {
|
||||
const output_info = globals.outputs_info.?.findOutputByName(mw.monitor) orelse {
|
||||
std.log.warn("Monitor {s} not found", .{mw.monitor});
|
||||
continue;
|
||||
};
|
||||
|
||||
try preload.preload(mw.wallpaper);
|
||||
|
||||
var rendered = try Render.init(
|
||||
alloc,
|
||||
globals.compositor,
|
||||
globals.display,
|
||||
globals.layer_shell,
|
||||
output_info,
|
||||
&preload,
|
||||
);
|
||||
std.debug.print("{s}\n", .{mw.wallpaper});
|
||||
try rendered.setWallpaper(mw.wallpaper);
|
||||
try rendered_outputs.append(&rendered);
|
||||
}
|
||||
|
@ -135,9 +139,10 @@ fn runMainInstance(alloc: Allocator) !u8 {
|
|||
return 1;
|
||||
}
|
||||
|
||||
const MAX_EVENT_COUNT: usize = 10;
|
||||
while (true) {
|
||||
var epoll_events: [2]c.epoll_event = undefined;
|
||||
const ev_count = c.epoll_wait(epoll_fd, &epoll_events, 2, -1);
|
||||
var epoll_events: [MAX_EVENT_COUNT]c.epoll_event = undefined;
|
||||
const ev_count = c.epoll_wait(epoll_fd, &epoll_events, MAX_EVENT_COUNT, -1);
|
||||
if (ev_count == -1) {
|
||||
std.log.err("epoll wait failed", .{});
|
||||
return 1;
|
||||
|
@ -147,7 +152,7 @@ fn runMainInstance(alloc: Allocator) !u8 {
|
|||
while (i <= ev_count) : (i += 1) {
|
||||
if (epoll_events[i].data.fd == display_fd) {
|
||||
std.log.info("epoll display global event", .{});
|
||||
if (globals.display.dispatch() != .SUCCESS) return error.foo;
|
||||
if (globals.display.roundtrip() != .SUCCESS) return error.RoundTripFail;
|
||||
}
|
||||
if (epoll_events[i].data.fd == server.fd) {
|
||||
std.log.info("epoll socket server event", .{});
|
||||
|
|
|
@ -46,7 +46,8 @@ pub fn init(alloc: Allocator, globals: *Globals) !Server {
|
|||
|
||||
pub fn handleConnection(self: *Server) !void {
|
||||
const connection = try self.stream_server.accept();
|
||||
defer connection.stream.close();
|
||||
errdefer connection.stream.close();
|
||||
|
||||
std.log.info("Accepting incoming connection...", .{});
|
||||
|
||||
var buff: [std.fs.MAX_PATH_BYTES + 200]u8 = undefined;
|
||||
|
@ -57,6 +58,18 @@ pub fn handleConnection(self: *Server) !void {
|
|||
var it = std.mem.splitAny(u8, buff[0..response_size], " =");
|
||||
|
||||
if (it.next()) |command| {
|
||||
if (std.mem.eql(u8, "preload", command)) {
|
||||
if (it.next()) |wallpaper| {
|
||||
self.globals.preloaded.?.preload(std.mem.trim(u8, wallpaper, "\x0a")) catch |err| {
|
||||
std.log.err("{s}", .{@errorName(err)});
|
||||
_ = try connection.stream.write(@errorName(err));
|
||||
return;
|
||||
};
|
||||
_ = try connection.stream.write("preloaded successfully");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, "wallpaper", command)) {
|
||||
if (it.next()) |monitor| {
|
||||
if (it.next()) |wallpaper| {
|
||||
|
@ -65,10 +78,11 @@ pub fn handleConnection(self: *Server) !void {
|
|||
if (std.mem.eql(u8, output.output_info.name.?, monitor)) {
|
||||
// Trimming because socat add a trailing space
|
||||
self.globals.rendered_outputs.?[i].setWallpaper(std.mem.trim(u8, wallpaper, "\x0a")) catch |err| {
|
||||
std.log.debug("{s}", .{@errorName(err)});
|
||||
break;
|
||||
std.log.err("{s}", .{@errorName(err)});
|
||||
_ = try connection.stream.write(@errorName(err));
|
||||
return;
|
||||
};
|
||||
_ = try connection.stream.write("changed successfully");
|
||||
_ = try connection.stream.write("Changed successfully!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +91,13 @@ pub fn handleConnection(self: *Server) !void {
|
|||
return error.RenderedOutputsNull;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (std.mem.eql(u8, "unload", command)) {
|
||||
if (it.next()) |wallpaper| {
|
||||
self.globals.preloaded.?.unload(wallpaper);
|
||||
_ = try connection.stream.write("Unloaded successfully!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,5 +34,5 @@ end
|
|||
|
||||
os.execute("river")
|
||||
|
||||
buildZigScripts(listDirectories())
|
||||
buildzigscripts(listdirectories())
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ fn getActiveMonitor(alloc: Allocator, signature: ?[]const u8) ![]const u8 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn setWallpaperToCurrentMonitorHyprland(alloc: Allocator, path: []const u8) !void {
|
||||
pub fn setWallpaperToCurrentMonitorHyprpaper(alloc: Allocator, path: []const u8) !void {
|
||||
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer arena.deinit();
|
||||
|
||||
|
@ -83,8 +83,10 @@ pub fn setWallpaperToCurrentMonitorAestuarium(alloc: Allocator, path: []const u8
|
|||
const aestuarium_socket_path =
|
||||
try std.fs.path.join(alloc, &.{ env, "aestuarium.sock" });
|
||||
|
||||
const stream = try std.net.connectUnixSocket(aestuarium_socket_path);
|
||||
defer stream.close();
|
||||
const preload_msg = try std.mem.concat(arena.allocator(), u8, &[_][]const u8{
|
||||
"preload ",
|
||||
path,
|
||||
});
|
||||
|
||||
const wallpaper_msg = try std.mem.concat(arena.allocator(), u8, &[_][]const u8{
|
||||
"wallpaper ",
|
||||
|
@ -93,7 +95,28 @@ pub fn setWallpaperToCurrentMonitorAestuarium(alloc: Allocator, path: []const u8
|
|||
path,
|
||||
});
|
||||
|
||||
_ = try stream.write(wallpaper_msg);
|
||||
const bytes_len = try stream.read(&buf);
|
||||
std.log.info("{s}", .{buf[0..bytes_len]});
|
||||
const unload_msg = "unload all";
|
||||
|
||||
var bytes: usize = 0;
|
||||
{
|
||||
const stream = try std.net.connectUnixSocket(aestuarium_socket_path);
|
||||
defer stream.close();
|
||||
_ = try stream.write(preload_msg);
|
||||
bytes = try stream.read(&buf);
|
||||
std.log.info("{s}", .{buf[0..bytes]});
|
||||
}
|
||||
{
|
||||
const stream = try std.net.connectUnixSocket(aestuarium_socket_path);
|
||||
defer stream.close();
|
||||
_ = try stream.write(wallpaper_msg);
|
||||
bytes = try stream.read(&buf);
|
||||
std.log.info("{s}", .{buf[0..bytes]});
|
||||
}
|
||||
{
|
||||
const stream = try std.net.connectUnixSocket(aestuarium_socket_path);
|
||||
defer stream.close();
|
||||
_ = try stream.write(unload_msg);
|
||||
bytes = try stream.read(&buf);
|
||||
std.log.info("{s}", .{buf[0..bytes]});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue