diff options
Diffstat (limited to 'riverctl')
| -rw-r--r-- | riverctl/main.zig | 9 | ||||
| -rw-r--r-- | riverctl/options.zig | 154 |
2 files changed, 88 insertions, 75 deletions
diff --git a/riverctl/main.zig b/riverctl/main.zig index ebffb39..6fd6341 100644 --- a/riverctl/main.zig +++ b/riverctl/main.zig @@ -22,6 +22,7 @@ const assert = std.debug.assert; const wayland = @import("wayland"); const wl = wayland.client.wl; +const river = wayland.client.river; const zriver = wayland.client.zriver; const zxdg = wayland.client.zxdg; @@ -36,7 +37,7 @@ pub const Output = struct { pub const Globals = struct { control: ?*zriver.ControlV1 = null, - options_manager: ?*zriver.OptionsManagerV1 = null, + options_manager: ?*river.OptionsManagerV2 = null, status_manager: ?*zriver.StatusManagerV1 = null, seat: ?*wl.Seat = null, output_manager: ?*zxdg.OutputManagerV1 = null, @@ -87,6 +88,8 @@ fn _main() !void { try options.getOption(display, &globals); } else if (os.argv.len > 2 and mem.eql(u8, "set-option", mem.span(os.argv[1]))) { try options.setOption(display, &globals); + } else if (os.argv.len > 2 and mem.eql(u8, "unset-option", mem.span(os.argv[1]))) { + try options.unsetOption(display, &globals); } else if (os.argv.len > 2 and mem.eql(u8, "mod-option", mem.span(os.argv[1]))) { try options.modOption(display, &globals); } else { @@ -115,8 +118,8 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: * globals.seat = registry.bind(global.name, wl.Seat, 1) catch @panic("out of memory"); } else if (std.cstr.cmp(global.interface, zriver.ControlV1.getInterface().name) == 0) { globals.control = registry.bind(global.name, zriver.ControlV1, 1) catch @panic("out of memory"); - } else if (std.cstr.cmp(global.interface, zriver.OptionsManagerV1.getInterface().name) == 0) { - globals.options_manager = registry.bind(global.name, zriver.OptionsManagerV1, 1) catch @panic("out of memory"); + } else if (std.cstr.cmp(global.interface, river.OptionsManagerV2.getInterface().name) == 0) { + globals.options_manager = registry.bind(global.name, river.OptionsManagerV2, 1) catch @panic("out of memory"); } else if (std.cstr.cmp(global.interface, zriver.StatusManagerV1.getInterface().name) == 0) { globals.status_manager = registry.bind(global.name, zriver.StatusManagerV1, 1) catch @panic("out of memory"); } else if (std.cstr.cmp(global.interface, zxdg.OutputManagerV1.getInterface().name) == 0 and global.version >= 2) { diff --git a/riverctl/options.zig b/riverctl/options.zig index aab9fa0..9501610 100644 --- a/riverctl/options.zig +++ b/riverctl/options.zig @@ -17,11 +17,13 @@ const std = @import("std"); const os = std.os; +const math = std.math; const mem = std.mem; const fmt = std.fmt; const wayland = @import("wayland"); const wl = wayland.client.wl; +const river = wayland.client.river; const zriver = wayland.client.zriver; const zxdg = wayland.client.zxdg; @@ -49,69 +51,42 @@ const Context = struct { pub fn declareOption(display: *wl.Display, globals: *Globals) !void { // https://github.com/ziglang/zig/issues/7807 const argv: [][*:0]const u8 = os.argv; - const args = Args(3, &[_]FlagDef{ - .{ .name = "-output", .kind = .arg }, - .{ .name = "-focused-output", .kind = .boolean }, - }).parse(argv[2..]); + const args = Args(3, &[_]FlagDef{}).parse(argv[2..]); const key = args.positionals[0]; - const value_type = std.meta.stringToEnum(ValueType, mem.span(args.positionals[1])) orelse - root.printErrorExit("'{}' is not a valid type, must be int, uint, fixed, or string", .{args.positionals[1]}); + const value_type = std.meta.stringToEnum(ValueType, mem.span(args.positionals[1])) orelse { + root.printErrorExit( + "'{}' is not a valid type, must be int, uint, fixed, or string", + .{args.positionals[1]}, + ); + }; const raw_value = args.positionals[2]; - const output = if (args.argFlag("-output")) |o| - try parseOutputName(display, globals, o) - else if (args.boolFlag("-focused-output")) - try getFocusedOutput(display, globals) - else - null; - const options_manager = globals.options_manager orelse return error.RiverOptionsManagerNotAdvertised; - const handle = try options_manager.getOptionHandle(key, if (output) |o| o.wl_output else null); switch (value_type) { - .int => setIntValueRaw(handle, raw_value), - .uint => setUintValueRaw(handle, raw_value), - .fixed => setFixedValueRaw(handle, raw_value), - .string => handle.setStringValue(if (raw_value[0] == 0) null else raw_value), + .int => options_manager.declareIntOption(key, parseInt(raw_value)), + .uint => options_manager.declareUintOption(key, parseUint(raw_value)), + .fixed => options_manager.declareFixedOption(key, parseFixed(raw_value)), + .string => options_manager.declareStringOption(key, raw_value), } - _ = display.flush() catch os.exit(1); -} -fn setIntValueRaw(handle: *zriver.OptionHandleV1, raw_value: [*:0]const u8) void { - handle.setIntValue(fmt.parseInt(i32, mem.span(raw_value), 10) catch - root.printErrorExit("{} is not a valid int", .{raw_value})); + _ = try display.flush(); } -fn setUintValueRaw(handle: *zriver.OptionHandleV1, raw_value: [*:0]const u8) void { - handle.setUintValue(fmt.parseInt(u32, mem.span(raw_value), 10) catch - root.printErrorExit("{} is not a valid uint", .{raw_value})); +fn parseInt(raw_value: [*:0]const u8) i32 { + return fmt.parseInt(i32, mem.span(raw_value), 10) catch + root.printErrorExit("{} is not a valid int", .{raw_value}); } -fn setFixedValueRaw(handle: *zriver.OptionHandleV1, raw_value: [*:0]const u8) void { - handle.setFixedValue(wl.Fixed.fromDouble(fmt.parseFloat(f64, mem.span(raw_value)) catch - root.printErrorExit("{} is not a valid fixed", .{raw_value}))); +fn parseUint(raw_value: [*:0]const u8) u32 { + return fmt.parseInt(u32, mem.span(raw_value), 10) catch + root.printErrorExit("{} is not a valid uint", .{raw_value}); } -fn modIntValueRaw(handle: *zriver.OptionHandleV1, current: i32, raw_value: [*:0]const u8) void { - const mod = fmt.parseInt(i32, mem.span(raw_value), 10) catch - root.printErrorExit("{} is not a valid int modificator", .{raw_value}); - handle.setIntValue(current + mod); -} - -fn modUintValueRaw(handle: *zriver.OptionHandleV1, current: u32, raw_value: [*:0]const u8) void { - // We need to allow negative mod values, but the value of the option may - // never be below zero. - const mod = fmt.parseInt(i32, mem.span(raw_value), 10) catch - root.printErrorExit("{} is not a valid uint modificator", .{raw_value}); - const new = @intCast(i32, current) + mod; - handle.setUintValue(if (new < 0) 0 else @intCast(u32, new)); -} - -fn modFixedValueRaw(handle: *zriver.OptionHandleV1, current: wl.Fixed, raw_value: [*:0]const u8) void { - const mod = fmt.parseFloat(f64, mem.span(raw_value)) catch - root.printErrorExit("{} is not a valid fixed modificator", .{raw_value}); - handle.setFixedValue(wl.Fixed.fromDouble(current.toDouble() + mod)); +fn parseFixed(raw_value: [*:0]const u8) wl.Fixed { + return wl.Fixed.fromDouble(fmt.parseFloat(f64, mem.span(raw_value)) catch + root.printErrorExit("{} is not a valid fixed", .{raw_value})); } pub fn getOption(display: *wl.Display, globals: *Globals) !void { @@ -174,6 +149,30 @@ pub fn setOption(display: *wl.Display, globals: *Globals) !void { while (true) _ = try display.dispatch(); } +pub fn unsetOption(display: *wl.Display, globals: *Globals) !void { + // https://github.com/ziglang/zig/issues/7807 + const argv: [][*:0]const u8 = os.argv; + const args = Args(1, &[_]FlagDef{ + .{ .name = "-output", .kind = .arg }, + .{ .name = "-focused-output", .kind = .boolean }, + }).parse(argv[2..]); + + const output = if (args.argFlag("-output")) |o| + try parseOutputName(display, globals, o) + else if (args.boolFlag("-focused-output")) + try getFocusedOutput(display, globals) + else + root.printErrorExit("unset requires either -output or -focused-output", .{}); + + const key = args.positionals[0]; + + const options_manager = globals.options_manager orelse return error.RiverOptionsManagerNotAdvertised; + + options_manager.unsetOption(key, output.wl_output); + + _ = try display.flush(); +} + pub fn modOption(display: *wl.Display, globals: *Globals) !void { // https://github.com/ziglang/zig/issues/7807 const argv: [][*:0]const u8 = os.argv; @@ -246,16 +245,12 @@ fn seatStatusListener(seat_status: *zriver.SeatStatusV1, event: zriver.SeatStatu } fn getOptionListener( - handle: *zriver.OptionHandleV1, - event: zriver.OptionHandleV1.Event, + handle: *river.OptionHandleV2, + event: river.OptionHandleV2.Event, ctx: *const Context, ) void { switch (event) { - .unset => if (ctx.output) |output| { - root.printErrorExit("option '{}' has not been declared on output '{}'", .{ ctx.key, output.name }); - } else { - root.printErrorExit("option '{}' has not been declared globally", .{ctx.key}); - }, + .undeclared => root.printErrorExit("option '{}' has not been declared", .{ctx.key}), .int_value => |ev| printOutputExit("{}", .{ev.value}), .uint_value => |ev| printOutputExit("{}", .{ev.value}), .fixed_value => |ev| printOutputExit("{d}", .{ev.value.toDouble()}), @@ -270,19 +265,15 @@ fn printOutputExit(comptime format: []const u8, args: anytype) noreturn { } fn setOptionListener( - handle: *zriver.OptionHandleV1, - event: zriver.OptionHandleV1.Event, + handle: *river.OptionHandleV2, + event: river.OptionHandleV2.Event, ctx: *const Context, ) void { switch (event) { - .unset => if (ctx.output) |output| { - root.printErrorExit("option '{}' has not been declared on output '{}'", .{ ctx.key, output.name }); - } else { - root.printErrorExit("option '{}' has not been declared globally", .{ctx.key}); - }, - .int_value => |ev| setIntValueRaw(handle, ctx.raw_value), - .uint_value => |ev| setUintValueRaw(handle, ctx.raw_value), - .fixed_value => |ev| setFixedValueRaw(handle, ctx.raw_value), + .undeclared => root.printErrorExit("option '{}' has not been declared", .{ctx.key}), + .int_value => |ev| handle.setIntValue(parseInt(ctx.raw_value)), + .uint_value => |ev| handle.setUintValue(parseUint(ctx.raw_value)), + .fixed_value => |ev| handle.setFixedValue(parseFixed(ctx.raw_value)), .string_value => |ev| handle.setStringValue(if (ctx.raw_value[0] == 0) null else ctx.raw_value), } _ = ctx.display.flush() catch os.exit(1); @@ -290,16 +281,12 @@ fn setOptionListener( } fn modOptionListener( - handle: *zriver.OptionHandleV1, - event: zriver.OptionHandleV1.Event, + handle: *river.OptionHandleV2, + event: river.OptionHandleV2.Event, ctx: *const Context, ) void { switch (event) { - .unset => if (ctx.output) |output| { - root.printErrorExit("option '{}' has not been declared on output '{}'", .{ ctx.key, output.name }); - } else { - root.printErrorExit("option '{}' has not been declared globally", .{ctx.key}); - }, + .undeclared => root.printErrorExit("option '{}' has not been declared", .{ctx.key}), .int_value => |ev| modIntValueRaw(handle, ev.value, ctx.raw_value), .uint_value => |ev| modUintValueRaw(handle, ev.value, ctx.raw_value), .fixed_value => |ev| modFixedValueRaw(handle, ev.value, ctx.raw_value), @@ -308,3 +295,26 @@ fn modOptionListener( _ = ctx.display.flush() catch os.exit(1); os.exit(0); } + +fn modIntValueRaw(handle: *river.OptionHandleV2, current: i32, raw_value: [*:0]const u8) void { + const mod = fmt.parseInt(i32, mem.span(raw_value), 10) catch + root.printErrorExit("{} is not a valid int modifier", .{raw_value}); + const new_value = math.add(i32, current, mod) catch + root.printErrorExit("provided value of {d} would overflow option if added", .{mod}); + handle.setIntValue(new_value); +} + +fn modUintValueRaw(handle: *river.OptionHandleV2, current: u32, raw_value: [*:0]const u8) void { + // We need to allow negative mod values, but the value of the option may + // never be below zero. + const mod = fmt.parseInt(i32, mem.span(raw_value), 10) catch + root.printErrorExit("{} is not a valid uint modifier", .{raw_value}); + const new = @intCast(i32, current) + mod; + handle.setUintValue(if (new < 0) 0 else @intCast(u32, new)); +} + +fn modFixedValueRaw(handle: *river.OptionHandleV2, current: wl.Fixed, raw_value: [*:0]const u8) void { + const mod = fmt.parseFloat(f64, mem.span(raw_value)) catch + root.printErrorExit("{} is not a valid fixed modifier", .{raw_value}); + handle.setFixedValue(wl.Fixed.fromDouble(current.toDouble() + mod)); +} |
