ambrop7 15 лет назад
Родитель
Сommit
68d6ec0b9b
1 измененных файлов с 143 добавлено и 0 удалено
  1. 143 0
      ncd/examples/volumekeys.ncd

+ 143 - 0
ncd/examples/volumekeys.ncd

@@ -0,0 +1,143 @@
+#
+# NCD volume key handling program.
+#
+# This program responds to volume key presses by synchronously calling an external
+# script for muting and adjusting volume.
+#
+# It uses process_manager() and sys.watch_directory() to dynamically create and remove
+# processes that deal with specific input devices. The individual input device processes
+# then use sys.evdev() to handle input events from specific devices.
+#
+
+process volumekeys_main {
+    # Directory to watch for input devices.
+    var("/dev/input/by-path") watch_dir;
+    # Regular expression for device names to work with.
+    var("-event$") watch_regex;
+    # Volume control script, called with argument "up", "down" or "mute".
+    var("/usr/local/bin/volumekey") volume_script;
+
+    # Provide for accessing configuration from event providers.
+    provide("volumekeys_config");
+
+    # Create process manager.
+    process_manager() manager;
+
+    # Wait for directory events.
+    sys.watch_directory(watch_dir) watcher;
+
+    # Determine if the device is of interest.
+    regex_match(watcher.filename, watch_regex) match;
+
+    # Determine dispatch location.
+    strcmp(watcher.event_type, "added") added;
+    and(added, match.succeeded) dispatch_added;
+    strcmp(watcher.event_type, "removed") removed;
+    and(removed, match.succeeded) dispatch_removed;
+
+    # Dispatch event.
+    provide("volumekeys_directory_event");
+
+    # If event was not recognized, finish it here.
+    ifnot(dispatch_added);
+    ifnot(dispatch_removed);
+    watcher->nextevent();
+}
+
+process volumekeys_directory_event_added {
+    # Wait for event.
+    depend("volumekeys_directory_event") evdep;
+    if(evdep.dispatch_added);
+
+    # Start event handling process for this device.
+    list(evdep.watcher.filepath) args;
+    evdep.manager->start(evdep.watcher.filename, "volumekeys_input_device", args);
+
+    # Finish event.
+    evdep.watcher->nextevent();
+}
+
+process volumekeys_directory_event_removed {
+    # Wait for event.
+    depend("volumekeys_directory_event") evdep;
+    if(evdep.dispatch_removed);
+
+    # Stop event handling process for this device.
+    evdep.manager->stop(evdep.watcher.filename);
+
+    # Finish event.
+    evdep.watcher->nextevent();
+}
+
+template volumekeys_input_device {
+    # Alias arguments.
+    var(_arg0) dev;
+
+    # Dependency for accessing configuration.
+    depend("volumekeys_config") config;
+
+    # Wait for input events.
+    sys.evdev(dev) evdev;
+
+    # Query event details.
+    strcmp(evdev.code, "KEY_MUTE") is_mute;
+    strcmp(evdev.code, "KEY_VOLUMEUP") is_vup;
+    strcmp(evdev.code, "KEY_VOLUMEDOWN") is_vdown;
+    strcmp(evdev.value, "1") is_pressed;
+
+    # Compute where to dispatch the event.
+    and(is_mute, is_pressed) dispatch_mute;
+    and(is_vup, is_pressed) dispatch_vup;
+    and(is_vdown, is_pressed) dispatch_vdown;
+
+    # Dispatch event.
+    provide_event("volumekeys_input_event");
+
+    # If event was not recognized, finish it here.
+    ifnot(dispatch_mute);
+    ifnot(dispatch_vup);
+    ifnot(dispatch_vdown);
+    evdev->nextevent();
+}
+
+process event_mute {
+    # Wait for event.
+    depend("volumekeys_input_event") dep;
+    if(dep.dispatch_mute);
+
+    # Process event.
+    list(dep.config.volume_script, "mute") do;
+    list("/bin/true") undo;
+    run(do, undo);
+
+    # Finish event.
+    dep.evdev->nextevent();
+}
+
+process event_vup {
+    # Wait for event.
+    depend("volumekeys_input_event") dep;
+    if(dep.dispatch_vup);
+
+    # Process event.
+    list(dep.config.volume_script, "up") do;
+    list("/bin/true") undo;
+    run(do, undo);
+
+    # Finish event.
+    dep.evdev->nextevent();
+}
+
+process event_vdown {
+    # Wait for event.
+    depend("volumekeys_input_event") dep;
+    if(dep.dispatch_vdown);
+
+    # Process event.
+    list(dep.config.volume_script, "down") do;
+    list("/bin/true") undo;
+    run(do, undo);
+
+    # Finish event.
+    dep.evdev->nextevent();
+}