keyboard: add the ability to load layout from file

This commit is contained in:
István Donkó
2023-08-12 21:30:55 +02:00
committed by Isaac Freund
parent 04dea1edee
commit 927dceb071
6 changed files with 50 additions and 0 deletions

View File

@ -62,6 +62,7 @@ const command_impls = std.ComptimeStringMap(
.{ "keyboard-group-destroy", @import("command/keyboard_group.zig").keyboardGroupDestroy },
.{ "keyboard-group-remove", @import("command/keyboard_group.zig").keyboardGroupRemove },
.{ "keyboard-layout", @import("command/keyboard.zig").keyboardLayout },
.{ "keyboard-layout-file", @import("command/keyboard.zig").keyboardLayoutFile },
.{ "list-input-configs", @import("command/input.zig").listInputConfigs},
.{ "list-inputs", @import("command/input.zig").listInputs },
.{ "list-rules", @import("command/rule.zig").listRules},
@ -112,6 +113,8 @@ pub const Error = error{
InvalidOrientation,
InvalidRgba,
InvalidValue,
CannotReadFile,
CannotParseFile,
UnknownOption,
ConflictingOptions,
OutOfMemory,
@ -155,6 +158,8 @@ pub fn errToMsg(err: Error) [:0]const u8 {
Error.InvalidOrientation => "invalid orientation. Must be 'horizontal', or 'vertical'",
Error.InvalidRgba => "invalid color format, must be hexadecimal 0xRRGGBB or 0xRRGGBBAA",
Error.InvalidValue => "invalid value",
Error.CannotReadFile => "cannot read file",
Error.CannotParseFile => "cannot parse file",
Error.OutOfMemory => "out of memory",
Error.Other => unreachable,
};

View File

@ -58,6 +58,42 @@ pub fn keyboardLayout(
) orelse return error.InvalidValue;
defer new_keymap.unref();
applyLayout(new_keymap);
}
pub fn keyboardLayoutFile(
_: *Seat,
args: []const [:0]const u8,
_: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
if (args.len > 2) return Error.TooManyArguments;
const file = std.fs.cwd().openFile(args[1], .{}) catch return error.CannotReadFile;
defer file.close();
// 1 GiB is arbitrarily chosen as an exceedingly large but not infinite upper bound.
const file_bytes = file.readToEndAlloc(util.gpa, 1024 * 1024 * 1024) catch |err| {
switch (err) {
error.FileTooBig, error.OutOfMemory => return error.OutOfMemory,
else => return error.CannotReadFile,
}
};
defer util.gpa.free(file_bytes);
const new_keymap = xkb.Keymap.newFromBuffer(
server.config.xkb_context,
file_bytes.ptr,
file_bytes.len,
.text_v1,
.no_flags,
) orelse return error.CannotParseFile;
defer new_keymap.unref();
applyLayout(new_keymap);
}
fn applyLayout(new_keymap: *xkb.Keymap) void {
server.config.keymap.unref();
server.config.keymap = new_keymap.ref();