about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJan Malakhovski <oxij@oxij.org>2015-04-15 17:48:38 +0000
committerJan Malakhovski <oxij@oxij.org>2015-04-20 17:11:19 +0000
commit57ab189e7807ade1432a5c02599ed11a7ee9cc37 (patch)
tree74aee967ccdb36ffbf0680655444ee7622b45889
parentbba9d17e943540413fe4d1b47ede03ac7f74da04 (diff)
downloadnixlib-57ab189e7807ade1432a5c02599ed11a7ee9cc37.tar
nixlib-57ab189e7807ade1432a5c02599ed11a7ee9cc37.tar.gz
nixlib-57ab189e7807ade1432a5c02599ed11a7ee9cc37.tar.bz2
nixlib-57ab189e7807ade1432a5c02599ed11a7ee9cc37.tar.lz
nixlib-57ab189e7807ade1432a5c02599ed11a7ee9cc37.tar.xz
nixlib-57ab189e7807ade1432a5c02599ed11a7ee9cc37.tar.zst
nixlib-57ab189e7807ade1432a5c02599ed11a7ee9cc37.zip
nixos: add actkbd module and sound.enableMediaKeys option
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/audio/alsa.nix27
-rw-r--r--nixos/modules/services/hardware/actkbd.nix130
3 files changed, 158 insertions, 0 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 1a9cce76ee91..e5da4fb2fb42 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -149,6 +149,7 @@
   ./services/games/minecraft-server.nix
   ./services/games/minetest-server.nix
   ./services/hardware/acpid.nix
+  ./services/hardware/actkbd.nix
   ./services/hardware/amd-hybrid-graphics.nix
   ./services/hardware/bluetooth.nix
   ./services/hardware/freefall.nix
diff --git a/nixos/modules/services/audio/alsa.nix b/nixos/modules/services/audio/alsa.nix
index 653c0ed5d70b..c63f4dc8d7f1 100644
--- a/nixos/modules/services/audio/alsa.nix
+++ b/nixos/modules/services/audio/alsa.nix
@@ -33,6 +33,16 @@ in
         '';
       };
 
+      enableMediaKeys = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable volume and capture control with keyboard media keys.
+
+          Enabling this will turn on <option>services.actkbd</option>.
+        '';
+      };
+
       extraConfig = mkOption {
         type = types.lines;
         default = "";
@@ -80,6 +90,23 @@ in
         };
       };
 
+    services.actkbd = mkIf config.sound.enableMediaKeys {
+      enable = true;
+      bindings = [
+        # "Mute" media key
+        { keys = [ 113 ]; events = [ "key" ];       command = "${alsaUtils}/bin/amixer -q set Master toggle"; }
+
+        # "Lower Volume" media key
+        { keys = [ 114 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1- unmute"; }
+
+        # "Raise Volume" media key
+        { keys = [ 115 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1+ unmute"; }
+
+        # "Mic Mute" media key
+        { keys = [ 190 ]; events = [ "key" ];       command = "${alsaUtils}/bin/amixer -q set Capture toggle"; }
+      ];
+    };
+
   };
 
 }
diff --git a/nixos/modules/services/hardware/actkbd.nix b/nixos/modules/services/hardware/actkbd.nix
new file mode 100644
index 000000000000..82de362c371b
--- /dev/null
+++ b/nixos/modules/services/hardware/actkbd.nix
@@ -0,0 +1,130 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.actkbd;
+
+  configFile = pkgs.writeText "actkbd.conf" ''
+    ${concatMapStringsSep "\n"
+      ({ keys, events, attributes, command, ... }:
+        ''${concatMapStringsSep "+" toString keys}:${concatStringsSep "," events}:${concatStringsSep "," attributes}:${command}''
+      )
+      cfg.bindings}
+    ${cfg.extraConfig}
+  '';
+
+  bindingCfg = { config, ... }: {
+    options = {
+
+      keys = mkOption {
+        type = types.listOf types.int;
+        description = "List of keycodes to match.";
+      };
+
+      events = mkOption {
+        type = types.listOf (types.enum ["key" "rep" "rel"]);
+        default = [ "key" ];
+        description = "List of events to match.";
+      };
+
+      attributes = mkOption {
+        type = types.listOf types.str;
+        default = [ "exec" ];
+        description = "List of attributes.";
+      };
+
+      command = mkOption {
+        type = types.str;
+        default = "";
+        description = "What to run.";
+      };
+
+    };
+  };
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.actkbd = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable the <command>actkbd</command> key mapping daemon.
+
+          Turning this on will start an <command>actkbd</command>
+          instance for every evdev input that has at least one key
+          (which is okay even for systems with tiny memory footprint,
+          since actkbd normally uses &lt;100 bytes of memory per
+          instance).
+
+          This allows binding keys globally without the need for e.g.
+          X11.
+        '';
+      };
+
+      bindings = mkOption {
+        type = types.listOf (types.submodule bindingCfg);
+        default = [];
+        example = lib.literalExample ''
+          [ { keys = [ 113 ]; events = [ "key" ]; command = "''${pkgs.alsaUtils}/bin/amixer -q set Master toggle"; }
+          ]
+        '';
+        description = ''
+          Key bindings for <command>actkbd</command>.
+
+          See <command>actkbd</command> <filename>README</filename> for documentation.
+
+          The example shows a piece of what <option>sound.enableMediaKeys</option> does when enabled.
+        '';
+      };
+
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Literal contents to append to the end of actkbd configuration file.
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.udev.packages = lib.singleton (pkgs.writeTextFile {
+      name = "actkbd-udev-rules";
+      destination = "/etc/udev/rules.d/61-actkbd.rules";
+      text = ''
+        ACTION=="add", SUBSYSTEM=="input", KERNEL=="event[0-9]*", ENV{ID_INPUT_KEY}=="1", TAG+="systemd", ENV{SYSTEMD_WANTS}+="actkbd@$env{DEVNAME}.service"
+      '';
+    });
+
+    systemd.services."actkbd@" = {
+      enable = true;
+      restartIfChanged = true;
+      unitConfig = {
+        Description = "actkbd on %I";
+        ConditionPathExists = "%I";
+      };
+      serviceConfig = {
+        Type = "forking";
+        ExecStart = "${pkgs.actkbd}/bin/actkbd -D -c ${configFile} -d %I";
+      };
+    };
+
+  };
+
+}