aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/tasks/kbd.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/tasks/kbd.nix')
-rw-r--r--nixpkgs/nixos/modules/tasks/kbd.nix127
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
+ '';
+ })
+ ]))
+ ];
+
+}