about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services/ttys/kmscon.nix
blob: f5a8d8b104d2f45d596cd28b38cbd7984b1ba879 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
{ config, pkgs, lib, ... }:
let
  inherit (lib) mapAttrs mkIf mkOption optional optionals types;

  cfg = config.services.kmscon;

  autologinArg = lib.optionalString (cfg.autologinUser != null) "-f ${cfg.autologinUser}";

  configDir = pkgs.writeTextFile { name = "kmscon-config"; destination = "/kmscon.conf"; text = cfg.extraConfig; };
in {
  options = {
    services.kmscon = {
      enable = mkOption {
        description = lib.mdDoc ''
          Use kmscon as the virtual console instead of gettys.
          kmscon is a kms/dri-based userspace virtual terminal implementation.
          It supports a richer feature set than the standard linux console VT,
          including full unicode support, and when the video card supports drm
          should be much faster.
        '';
        type = types.bool;
        default = false;
      };

      hwRender = mkOption {
        description = lib.mdDoc "Whether to use 3D hardware acceleration to render the console.";
        type = types.bool;
        default = false;
      };

      fonts = mkOption {
        description = lib.mdDoc "Fonts used by kmscon, in order of priority.";
        default = null;
        example = lib.literalExpression ''[ { name = "Source Code Pro"; package = pkgs.source-code-pro; } ]'';
        type = with types;
          let fontType = submodule {
                options = {
                  name = mkOption { type = str; description = lib.mdDoc "Font name, as used by fontconfig."; };
                  package = mkOption { type = package; description = lib.mdDoc "Package providing the font."; };
                };
          }; in nullOr (nonEmptyListOf fontType);
      };

      extraConfig = mkOption {
        description = lib.mdDoc "Extra contents of the kmscon.conf file.";
        type = types.lines;
        default = "";
        example = "font-size=14";
      };

      extraOptions = mkOption {
        description = lib.mdDoc "Extra flags to pass to kmscon.";
        type = types.separatedString " ";
        default = "";
        example = "--term xterm-256color";
      };

      autologinUser = mkOption {
        type = types.nullOr types.str;
        default = null;
        description = lib.mdDoc ''
          Username of the account that will be automatically logged in at the console.
          If unspecified, a login prompt is shown as usual.
        '';
      };
    };
  };

  config = mkIf cfg.enable {
    # Largely copied from unit provided with kmscon source
    systemd.units."kmsconvt@.service".text = ''
      [Unit]
      Description=KMS System Console on %I
      Documentation=man:kmscon(1)
      After=systemd-user-sessions.service
      After=plymouth-quit-wait.service
      After=systemd-logind.service
      After=systemd-vconsole-setup.service
      Requires=systemd-logind.service
      Before=getty.target
      Conflicts=getty@%i.service
      OnFailure=getty@%i.service
      IgnoreOnIsolate=yes
      ConditionPathExists=/dev/tty0

      [Service]
      ExecStart=
      ExecStart=${pkgs.kmscon}/bin/kmscon "--vt=%I" ${cfg.extraOptions} --seats=seat0 --no-switchvt --configdir ${configDir} --login -- ${pkgs.shadow}/bin/login -p ${autologinArg}
      UtmpIdentifier=%I
      TTYPath=/dev/%I
      TTYReset=yes
      TTYVHangup=yes
      TTYVTDisallocate=yes

      X-RestartIfChanged=false
    '';

    systemd.suppressedSystemUnits = [ "autovt@.service" ];
    systemd.units."kmsconvt@.service".aliases = [ "autovt@.service" ];

    systemd.services.systemd-vconsole-setup.enable = false;

    services.kmscon.extraConfig =
      let
        render = optionals cfg.hwRender [ "drm" "hwaccel" ];
        fonts = optional (cfg.fonts != null) "font-name=${lib.concatMapStringsSep ", " (f: f.name) cfg.fonts}";
      in lib.concatStringsSep "\n" (render ++ fonts);

    hardware.opengl.enable = mkIf cfg.hwRender true;

    fonts = mkIf (cfg.fonts != null) {
      fontconfig.enable = true;
      fonts = map (f: f.package) cfg.fonts;
    };
  };
}