aboutsummaryrefslogtreecommitdiff
path: root/extras/util
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 /extras/util
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.
Diffstat (limited to 'extras/util')
-rw-r--r--extras/util/automonitor/automonitor.c91
1 files changed, 91 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;
+ }
+ }
+}