diff options
Diffstat (limited to 'nixpkgs/nixos/modules/tasks/kbd.nix')
-rw-r--r-- | nixpkgs/nixos/modules/tasks/kbd.nix | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/tasks/kbd.nix b/nixpkgs/nixos/modules/tasks/kbd.nix new file mode 100644 index 00000000000..c6ba998b19e --- /dev/null +++ b/nixpkgs/nixos/modules/tasks/kbd.nix @@ -0,0 +1,127 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + makeColor = n: value: "COLOR_${toString n}=${value}"; + makeColorCS = + let positions = [ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ]; + in n: value: "\\033]P${elemAt positions (n - 1)}${value}"; + colors = concatImapStringsSep "\n" makeColor config.i18n.consoleColors; + + isUnicode = hasSuffix "UTF-8" (toUpper config.i18n.defaultLocale); + + optimizedKeymap = pkgs.runCommand "keymap" { + nativeBuildInputs = [ pkgs.buildPackages.kbd ]; + LOADKEYS_KEYMAP_PATH = "${kbdEnv}/share/keymaps/**"; + preferLocalBuild = true; + } '' + loadkeys -b ${optionalString isUnicode "-u"} "${config.i18n.consoleKeyMap}" > $out + ''; + + # Sadly, systemd-vconsole-setup doesn't support binary keymaps. + vconsoleConf = pkgs.writeText "vconsole.conf" '' + KEYMAP=${config.i18n.consoleKeyMap} + FONT=${config.i18n.consoleFont} + ${colors} + ''; + + kbdEnv = pkgs.buildEnv { + name = "kbd-env"; + paths = [ pkgs.kbd ] ++ config.i18n.consolePackages; + pathsToLink = [ "/share/consolefonts" "/share/consoletrans" "/share/keymaps" "/share/unimaps" ]; + }; + + setVconsole = !config.boot.isContainer; +in + +{ + ###### interface + + options = { + + # most options are defined in i18n.nix + + # FIXME: still needed? + boot.extraTTYs = mkOption { + default = []; + type = types.listOf types.str; + example = ["tty8" "tty9"]; + description = '' + Tty (virtual console) devices, in addition to the consoles on + which mingetty and syslogd run, that must be initialised. + Only useful if you have some program that you want to run on + some fixed console. For example, the NixOS installation CD + opens the manual in a web browser on console 7, so it sets + <option>boot.extraTTYs</option> to <literal>["tty7"]</literal>. + ''; + }; + + boot.earlyVconsoleSetup = mkOption { + default = false; + type = types.bool; + description = '' + Enable setting font as early as possible (in initrd). + ''; + }; + + }; + + + ###### implementation + + config = mkMerge [ + (mkIf (!setVconsole) { + systemd.services.systemd-vconsole-setup.enable = false; + }) + + (mkIf setVconsole (mkMerge [ + { environment.systemPackages = [ pkgs.kbd ]; + + # Let systemd-vconsole-setup.service do the work of setting up the + # virtual consoles. + environment.etc."vconsole.conf".source = vconsoleConf; + # Provide kbd with additional packages. + environment.etc.kbd.source = "${kbdEnv}/share"; + + boot.initrd.preLVMCommands = mkBefore '' + kbd_mode ${if isUnicode then "-u" else "-a"} -C /dev/console + printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console + loadkmap < ${optimizedKeymap} + + ${optionalString config.boot.earlyVconsoleSetup '' + setfont -C /dev/console $extraUtils/share/consolefonts/font.psf + ''} + + ${concatImapStringsSep "\n" (n: color: '' + printf "${makeColorCS n color}" >> /dev/console + '') config.i18n.consoleColors} + ''; + + systemd.services.systemd-vconsole-setup = + { before = [ "display-manager.service" ]; + after = [ "systemd-udev-settle.service" ]; + restartTriggers = [ vconsoleConf kbdEnv ]; + }; + } + + (mkIf config.boot.earlyVconsoleSetup { + boot.initrd.extraUtilsCommands = '' + mkdir -p $out/share/consolefonts + ${if substring 0 1 config.i18n.consoleFont == "/" then '' + font="${config.i18n.consoleFont}" + '' else '' + font="$(echo ${kbdEnv}/share/consolefonts/${config.i18n.consoleFont}.*)" + ''} + if [[ $font == *.gz ]]; then + gzip -cd $font > $out/share/consolefonts/font.psf + else + cp -L $font $out/share/consolefonts/font.psf + fi + ''; + }) + ])) + ]; + +} |