depot/third_party/nixpkgs/nixos/modules/services/hardware/buffyboard.nix

138 lines
4.6 KiB
Nix

# INTEGRATION NOTES:
# Buffyboard integrates as a virtual device in /dev/input
# which reads touch or pointer events from other input devices
# and generates events based on where those map to the keys it renders to the framebuffer.
#
# Buffyboard generates these events whether or not its onscreen keyboard is actually visible.
# Hence special care is needed if running anything which claims ownership of the display (such as a desktop environment),
# to avoid unwanted input events being triggered during normal desktop operation.
#
# Desktop users are recommended to either:
# 1. Stop buffyboard once your DE is started.
# e.g. `services.buffyboard.unitConfig.Conflicts = [ "my-de.service" ];`
# 2. Configure your DE to ignore input events from buffyboard (product-id=25209; vendor-id=26214; name=rd)
# e.g. `echo 'input "26214:25209:rd" events disabled' > ~/.config/sway/config`
{
config,
lib,
pkgs,
utils,
...
}:
let
cfg = config.services.buffyboard;
ini = pkgs.formats.ini { };
in
{
meta.maintainers = with lib.maintainers; [ colinsane ];
options = {
services.buffyboard = with lib; {
enable = mkEnableOption "buffyboard framebuffer keyboard (on-screen keyboard)";
package = mkPackageOption pkgs "buffybox" { };
extraFlags = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Extra CLI arguments to pass to buffyboard.
'';
example = [
"--geometry=1920x1080@640,0"
"--dpi=192"
"--rotate=2"
"--verbose"
];
};
configFile = mkOption {
type = lib.types.path;
default = ini.generate "buffyboard.conf" (lib.filterAttrsRecursive (_: v: v != null) cfg.settings);
defaultText = lib.literalExpression ''ini.generate "buffyboard.conf" cfg.settings'';
description = ''
Path to an INI format configuration file to provide Buffyboard.
By default, this is generated from whatever you've set in `settings`.
If specified manually, then `settings` is ignored.
For an example config file see [here](https://gitlab.postmarketos.org/postmarketOS/buffybox/-/blob/master/buffyboard/buffyboard.conf)
'';
};
settings = mkOption {
description = ''
Settings to include in /etc/buffyboard.conf.
Every option here is strictly optional:
Buffyboard will use its own baked-in defaults for those options left unset.
'';
type = types.submodule {
freeformType = ini.type;
options.input.pointer = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Enable or disable the use of a hardware mouse or other pointing device.
'';
};
options.input.touchscreen = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Enable or disable the use of the touchscreen.
'';
};
options.theme.default = mkOption {
type = types.either types.str (
types.enum [
null
"adwaita-dark"
"breezy-dark"
"breezy-light"
"nord-dark"
"nord-light"
"pmos-dark"
"pmos-light"
]
);
default = null;
description = ''
Selects the default theme on boot. Can be changed at runtime to the alternative theme.
'';
};
options.quirks.fbdev_force_refresh = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
If true and using the framebuffer backend, this triggers a display refresh after every draw operation.
This has a negative performance impact.
'';
};
};
default = { };
};
};
};
config = lib.mkIf cfg.enable {
systemd.packages = [ cfg.package ];
systemd.services.buffyboard = {
# upstream provides the service (including systemd hardening): we just configure it to start by default
# and override ExecStart so as to optionally pass extra arguments
serviceConfig.ExecStart = [
"" # clear default ExecStart
(utils.escapeSystemdExecArgs (
[
(lib.getExe' cfg.package "buffyboard")
"--config-override"
cfg.configFile
]
++ cfg.extraFlags
))
];
wantedBy = [ "getty.target" ];
before = [ "getty.target" ];
};
};
}