diff options
| author | Josh Rahm <rahm@google.com> | 2024-01-24 12:02:34 -0700 |
|---|---|---|
| committer | Josh Rahm <rahm@google.com> | 2024-01-24 12:02:34 -0700 |
| commit | 1e9b72d85ceb619f601f7c3b8f6b5c07ec88355f (patch) | |
| tree | 1ceceefdcd01e1915a8299bcfbc5146f21875be5 | |
| parent | 836991558eefc53e7ff1f1db6a8faaf59aee9bb8 (diff) | |
| download | rde-1e9b72d85ceb619f601f7c3b8f6b5c07ec88355f.tar.gz rde-1e9b72d85ceb619f601f7c3b8f6b5c07ec88355f.tar.bz2 rde-1e9b72d85ceb619f601f7c3b8f6b5c07ec88355f.zip | |
Added automonitor.
Automonitor is a program that calls a bash script to configure displays
when it detects a change in the drm subsystem.
It's experimental and is not set up by default. It would need to be set
up explicitly somewhere for it to work.
| -rw-r--r-- | extras/util/automonitor/automonitor.c | 91 | ||||
| -rwxr-xr-x | install.sh | 6 |
2 files changed, 97 insertions, 0 deletions
diff --git a/extras/util/automonitor/automonitor.c b/extras/util/automonitor/automonitor.c new file mode 100644 index 0000000..f55e2f4 --- /dev/null +++ b/extras/util/automonitor/automonitor.c @@ -0,0 +1,91 @@ +#include <libudev.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/select.h> +#include <sys/wait.h> +#include <unistd.h> + +#define BLOCK_SIZE 512 +#define STRNCMP(s, cs) strncmp(s, cs, strlen(cs)) + +int execute_shell_script() { + char *home = getenv("HOME"); + + if (!home) { + fprintf(stderr, "No home environment variable."); + return 1; + } + + char script_path[4096]; + + snprintf(script_path, sizeof(script_path) - 1, + "%s/.xmonad/configure-displays", home); + + int f = fork(); + if (f == 0) { + // child process. + execl(script_path, script_path, "change", NULL); + perror("Exec failed"); + exit(1); + } else { + if (f == -1) { + perror("Forking failed"); + return 1; + } else { + waitpid(f, NULL, 0); + } + } + + return 0; +} + +int main() { + struct udev *udev; + struct udev_device *dev; + struct udev_monitor *mon; + int fd; + + udev = udev_new(); + if (!udev) { + fprintf(stderr, "Cannot create new udev context\n"); + return 1; + } + + mon = udev_monitor_new_from_netlink(udev, "udev"); + udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", NULL); + udev_monitor_enable_receiving(mon); + fd = udev_monitor_get_fd(mon); + + int found_event = 0; + while (1) { + fd_set fds; + struct timeval to = {0}; + if (found_event) { + to.tv_usec = 100000; + } + int ret; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + ret = select(fd + 1, &fds, NULL, NULL, found_event ? &to : NULL); + if (ret > 0 && FD_ISSET(fd, &fds)) { + dev = udev_monitor_receive_device(mon); + if (dev) { + if (STRNCMP(udev_device_get_action(dev), "change") == 0) { + printf("I: Change detected.\n"); + found_event = 1; + // Still need to clean up some trailing detected changes. + } + } + } else if (ret == 0 && found_event) { + printf("Executing shell script hook.\n"); + if (execute_shell_script()) { + fprintf(stderr, "Unable to execute shell script."); + }; + found_event = 0; + } + } +} @@ -15,6 +15,12 @@ cc -o \ xmobar/extras/battery/battery.c \ -lm +cc -o \ + build/extras/HOME/.xmonad/automonitor \ + extras/util/automonitor/automonitor.c \ + -ludev + + ln -sf "$(stack path --local-install-root)/bin/xmobar-weather" build/extras/HOME/.xmonad/xmobar-weather ln -sf "$(stack path --local-install-root)/bin/xmobar-weather" extras/HOME/.xmonad/xmobar-weather |