aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2024-01-24 12:02:34 -0700
committerJosh Rahm <rahm@google.com>2024-01-24 12:02:34 -0700
commit1e9b72d85ceb619f601f7c3b8f6b5c07ec88355f (patch)
tree1ceceefdcd01e1915a8299bcfbc5146f21875be5
parent836991558eefc53e7ff1f1db6a8faaf59aee9bb8 (diff)
downloadrde-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.c91
-rwxr-xr-xinstall.sh6
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;
+ }
+ }
+}
diff --git a/install.sh b/install.sh
index f862fe8..f0bfa14 100755
--- a/install.sh
+++ b/install.sh
@@ -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