From b5442735ff0f715f1d4ab1ca60905a721f23d98b Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 25 Nov 2024 07:58:06 +0000 Subject: [PATCH 1/2] buffybox: init at 3.2.0-unstable-2024-11-10 [buffybox](https://gitlab.postmarketos.org/postmarketOS/buffybox/) is a suite of graphical applications for the terminal. notably for nixpkgs, this includes `buffyboard`: an on-screen framebuffer keyboard especially useful for touch-only devices like mobile phones. `buffyboard` can be built and launched (as root) with no arguments: then tab to an unused TTY (e.g. Ctrl+Alt+F2) where an on-screen keyboard should now be visible (if not, try clicking in the bottom of the terminal to force a redraw). further configuration of buffyboard is possible by editing `/etc/buffyboard.conf` or passing CLI flags. --- pkgs/by-name/bu/buffybox/package.nix | 60 ++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 pkgs/by-name/bu/buffybox/package.nix diff --git a/pkgs/by-name/bu/buffybox/package.nix b/pkgs/by-name/bu/buffybox/package.nix new file mode 100644 index 000000000000..8dcef1f1f0f4 --- /dev/null +++ b/pkgs/by-name/bu/buffybox/package.nix @@ -0,0 +1,60 @@ +{ + fetchFromGitLab, + inih, + lib, + libdrm, + libinput, + libxkbcommon, + meson, + ninja, + pkg-config, + scdoc, + stdenv, + unstableGitUpdater, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "buffybox"; + version = "3.2.0-unstable-2024-11-10"; + + src = fetchFromGitLab { + domain = "gitlab.postmarketos.org"; + owner = "postmarketOS"; + repo = "buffybox"; + fetchSubmodules = true; # to use its vendored lvgl + rev = "07e324c17564cb9aab573259a8e0824a6806a751"; + hash = "sha256-JY9WqtRjDsQf1UVFnM6oTwyAuhlJvrhcSNJdEZ0zIus="; + }; + + depsBuildBuild = [ + pkg-config + ]; + + nativeBuildInputs = [ + meson + ninja + pkg-config + scdoc + ]; + + buildInputs = [ + inih + libdrm + libinput + libxkbcommon + ]; + + env.PKG_CONFIG_SYSTEMD_SYSTEMD_SYSTEM_UNIT_DIR = "${placeholder "out"}/lib/systemd/system"; + + strictDeps = true; + + passthru.updateScript = unstableGitUpdater { }; + + meta = with lib; { + description = "A suite of graphical applications for the terminal"; + homepage = "https://gitlab.postmarketos.org/postmarketOS/buffybox"; + license = licenses.gpl3Plus; + maintainers = with lib.maintainers; [ colinsane ]; + platforms = platforms.linux; + }; +}) From 900bd0d8e6203f51c25456e493a3b61cca59ac8b Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 25 Nov 2024 09:21:20 +0000 Subject: [PATCH 2/2] nixos/buffyboard: init [buffyboard](https://gitlab.postmarketos.org/postmarketOS/buffybox/-/tree/master/buffyboard) is the on-screen framebuffer keyboard provided by postmarketOS's buffybox project. enable this with `services.buffybox.enable = true;`: any additional settings are strictly optional. once enabled, tab to an unused TTY (e.g. Ctrl+Alt+F2) and use the mouse/touchpad/touchscreen to use the virtual keyboard. may require a manual `systemctl start buffybox` if enabled on an already-booted device. Co-authored-by: Luflosi --- .../manual/release-notes/rl-2505.section.md | 2 + nixos/modules/module-list.nix | 1 + .../modules/services/hardware/buffyboard.nix | 138 ++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 nixos/modules/services/hardware/buffyboard.nix diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index d55b5bfd42a7..b811b03f06de 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -16,6 +16,8 @@ - [Amazon CloudWatch Agent](https://github.com/aws/amazon-cloudwatch-agent), the official telemetry collector for AWS CloudWatch and AWS X-Ray. Available as [services.amazon-cloudwatch-agent](#opt-services.amazon-cloudwatch-agent.enable). +- [Buffyboard](https://gitlab.postmarketos.org/postmarketOS/buffybox/-/tree/master/buffyboard), a framebuffer on-screen keyboard. Available as [services.buffyboard](option.html#opt-services.buffyboard). + ## Backward Incompatibilities {#sec-release-25.05-incompatibilities} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 91ecee0ef265..767531f9e8ef 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -588,6 +588,7 @@ ./services/hardware/bluetooth.nix ./services/hardware/bolt.nix ./services/hardware/brltty.nix + ./services/hardware/buffyboard.nix ./services/hardware/ddccontrol.nix ./services/hardware/display.nix ./services/hardware/fancontrol.nix diff --git a/nixos/modules/services/hardware/buffyboard.nix b/nixos/modules/services/hardware/buffyboard.nix new file mode 100644 index 000000000000..f6cab16138c0 --- /dev/null +++ b/nixos/modules/services/hardware/buffyboard.nix @@ -0,0 +1,138 @@ +# 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" ]; + }; + }; +}