srctree

Gregory Mullen parent d42c77dd 7c69caa6
it works

src/gui.zig added: 124, removed: 70, total 54
@@ -1,6 +1,8 @@
const std = @import("std");
 
pub const obs = @cImport({
@cInclude("obs/util/darray.h");
 
@cInclude("obs/util/base.h");
@cInclude("obs/obs-module.h");
@cInclude("obs/obs-config.h");
@@ -8,32 +10,93 @@ pub const obs = @cImport({
@cInclude("obs/obs-properties.h");
@cInclude("obs/obs-service.h");
});
 
const obs_src_array = extern struct {
array: [*]?*obs.obs_source_t,
num: usize = 0,
capacity: usize = 0,
};
 
const obs_frontend_source_list = extern struct {
sources: extern union {
da: obs.darray,
src: obs_src_array,
},
};
 
const obs_frontend_cb = *const fn (?*anyopaque) callconv(.C) void;
extern "obs-frontend-api" fn obs_frontend_add_tools_menu_item(name: [*:0]const u8, cb: obs_frontend_cb, ?*anyopaque) void;
 
extern "obs-frontend-api" fn obs_frontend_get_current_scene() ?*obs.obs_source_t;
extern "obs-frontend-api" fn obs_frontend_set_current_scene(*obs.obs_source_t) callconv(.C) void;
extern "obs-frontend-api" fn obs_frontend_get_scene_names() callconv(.C) [*:null]?[*c]u8;
extern "obs-frontend-api" fn obs_frontend_get_scenes(?*obs_frontend_source_list) callconv(.C) void;
 
pub fn currentScene() ?[:0]const u8 {
_ = obs_frontend_get_current_scene() orelse return null;
extern "obs-frontend-api" fn obs_frontend_preview_program_trigger_transition() callconv(.C) void;
//extern "obs-frontend-api" fn obs_frontend_source_list_free(?*obs_frontend_source_list) callconv(.C) void;
 
//const t = @as(?*obs.obs_source_info, @ptrCast(scene));
pub const OBSScene = struct {
var last: i64 = 0;
var on_build = false;
 
//if (t.?.get_name) |_gn| {
// const name: ?[*c]const u8 = _gn(scene);
// if (name) |n| return std.mem.span(n);
//}
return null;
}
pub fn findScenes() void {
var scenes: obs_frontend_source_list = std.mem.zeroes(obs_frontend_source_list);
 
pub fn setCurrentScene(scene: ?*obs.obs_source_t) void {
obs_frontend_set_current_scene(scene);
}
obs_frontend_get_scenes(&scenes);
// TODO write a c compat header for this
//defer obs_frontend_source_list_free(&scenes);
std.debug.print("source data {any}\n", .{scenes.sources.src});
 
pub fn getSceneNames() [:null]?[*c]const u8 {
return std.mem.span(obs_frontend_get_scene_names());
}
const array: [*]?*obs.obs_source_t = @ptrCast(scenes.sources.src.array);
for (array[0..scenes.sources.src.num]) |src| {
//const scene: ?*obs.obs_scene_t = obs.obs_scene_from_source(src);
const name: [*c]const u8 = obs.obs_source_get_name(src);
//const uuid: [*c]const u8 = obs.obs_source_get_uuid(@ptrCast(scene));
std.debug.print("scene {s} \n", .{name});
}
}
 
pub fn requestBuild() void {
std.debug.print("request build\n", .{});
if (!on_build) swapPreview();
on_build = true;
last = std.time.milliTimestamp();
}
 
pub fn requestCode() void {
std.debug.print("request code\n", .{});
if (last < std.time.milliTimestamp() - 1500 and on_build) {
swapPreview();
}
on_build = false;
last = std.time.milliTimestamp();
}
 
pub fn swapPreview() void {
std.debug.print("swaping\n", .{});
obs_frontend_preview_program_trigger_transition();
}
 
pub fn currentScene() ?[:0]const u8 {
_ = obs_frontend_get_current_scene() orelse return null;
 
//const t = @as(?*obs.obs_source_info, @ptrCast(scene));
 
//if (t.?.get_name) |_gn| {
// const name: ?[*c]const u8 = _gn(scene);
// if (name) |n| return std.mem.span(n);
//}
return null;
}
 
pub fn setCurrentScene(scene: ?*obs.obs_source_t) void {
obs_frontend_set_current_scene(scene);
}
 
pub fn getSceneNames() [:null]?[*c]const u8 {
return std.mem.span(obs_frontend_get_scene_names());
}
};
 
pub fn init() void {
propertiesInit();
@@ -56,27 +119,27 @@ fn clicked(_: ?*anyopaque) callconv(.C) void {
obs.blog(obs.LOG_INFO, "clicked");
}
 
fn createService(_: ?*obs.struct_obs_data, _: ?*obs.struct_obs_service) callconv(.C) ?*anyopaque {
return null;
}
//fn createService(_: ?*obs.struct_obs_data, _: ?*obs.struct_obs_service) callconv(.C) ?*anyopaque {
// return null;
//}
//
//fn destroyService(_: ?*anyopaque) callconv(.C) void {}
//
//fn getName(_: ?*anyopaque) callconv(.C) [*:0]const u8 {
// return "Service Name";
//}
//
//fn getProperties(_: ?*anyopaque) callconv(.C) ?*obs.obs_properties_t {
// const ppts: ?*obs.obs_properties_t = obs.obs_properties_create();
//
// _ = obs.obs_properties_add_bool(ppts, "my_bool", obs.obs_module_text("MyBool"));
// return ppts;
//}
 
fn destroyService(_: ?*anyopaque) callconv(.C) void {}
 
fn getName(_: ?*anyopaque) callconv(.C) [*:0]const u8 {
return "Service Name";
}
 
fn getProperties(_: ?*anyopaque) callconv(.C) ?*obs.obs_properties_t {
const ppts: ?*obs.obs_properties_t = obs.obs_properties_create();
 
_ = obs.obs_properties_add_bool(ppts, "my_bool", obs.obs_module_text("MyBool"));
return ppts;
}
 
const focus_service: obs.obs_service_info = obs.obs_service_info{
.id = "focus_service",
.create = createService,
.destroy = destroyService,
.get_name = getName,
.get_properties = getProperties,
};
//const focus_service: obs.obs_service_info = obs.obs_service_info{
// .id = "focus_service",
// .create = createService,
// .destroy = destroyService,
// .get_name = getName,
// .get_properties = getProperties,
//};
 
src/root.zig added: 124, removed: 70, total 54
@@ -52,8 +52,9 @@ fn log(text: [*:0]const u8) void {
 
var arena: std.heap.ArenaAllocator = undefined;
var alloc: Allocator = undefined;
var running = true;
 
fn thread(_: ?*anyopaque) void {
fn watchSway(_: ?*anyopaque) void {
obs.blog(obs.LOG_INFO, "sway thread running");
var sway = sway_ipc.Connection.init(alloc) catch |err| {
logFmt("connection error {}", .{err});
@@ -64,26 +65,32 @@ fn thread(_: ?*anyopaque) void {
unreachable;
};
std.time.sleep(10_000_000_000);
for (0..10) |_| {
gui.OBSScene.findScenes();
while (running) {
const msg = sway.loop() catch {
log("unexpected read error");
unreachable;
};
 
if (gui.currentScene()) |name| {
logFmt("name {s}\n", .{name});
}
std.time.sleep(10_000_000);
std.time.sleep(100_000_000);
switch (msg.toStruct(alloc) catch {
log("unable to build struct");
continue;
}) {
.window => |w| logFmt("marks {s}", .{w.container.marks}),
.window => |w| {
for (w.container.marks) |mark| {
if (std.mem.eql(u8, mark, "build")) {
//std.debug.print("found {}\n", .{w.container});
gui.OBSScene.requestBuild();
break;
}
} else {
gui.OBSScene.requestCode();
}
},
}
}
for (gui.getSceneNames()) |name| {
logFmt("scene name: {s}", .{std.mem.span(name.?)});
}
log("sway-focus thread exit");
}
 
var threads: [1]std.Thread = undefined;
@@ -91,34 +98,18 @@ var threads: [1]std.Thread = undefined;
export fn obs_module_load() bool {
arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
alloc = arena.allocator();
threads[0] = std.Thread.spawn(.{}, thread, .{null}) catch unreachable;
threads[0] = std.Thread.spawn(.{}, watchSway, .{null}) catch unreachable;
 
enumScene();
logFmt("sway-focus plugin loaded successfully {s}", .{PLUGIN_VERSION});
 
return true;
}
 
export fn obs_module_unload() void {
log("sway-focus plugin shutdown");
running = false;
std.Thread.join(threads[0]);
arena.deinit();
}
 
fn enumScene() void {
obs.obs_enum_scenes(enumSceneCb, null);
}
 
fn enumSceneCb(_: ?*anyopaque, _: ?*obs.obs_source_t) callconv(.C) bool {
//const char: [*:0]u8 = scene.?.get_name(data);
 
//obs.blog(obs.LOG_INFO, "plugin data (found scene %s)", char);
return true;
}
 
fn enumSceneItemCb(_: ?*obs.obs_scene_t, _: ?*obs.obs_sceneitem_t, _: ?*void) callconv(.C) void {}
 
// TODO
// get windows
// trigger scene on event
// stall on remove for min seconds
 
test "basic add functionality" {}