From ca74d51f05f9748de24e24ff047f5c08a7145c78 Mon Sep 17 00:00:00 2001 From: Yuki Joou Date: Thu, 13 Jul 2023 13:53:44 +0200 Subject: [PATCH] usb_device_detection+main: Added hooks on basestation state change A script will now run whenever the basesation is plugged/unplugged. --- main.c | 80 ++++++++++++++++++++++++++++++++++++++++++ usb_device_detection.c | 10 ++++-- usb_device_detection.h | 6 ++++ 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index 81250ab..30178cb 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,10 @@ +// This is for asprintf support. +// TODO: Don't use asprintf and remove this. +#define _GNU_SOURCE + #include #include +#include #include @@ -21,6 +26,77 @@ static char const* const DEFAULT_MOTION_SENSOR = static uint16_t const BASESTATION_VENDOR_ID = 0x048d; static uint16_t const BASESTATION_PRODUCT_ID = 0x8911; +static char* get_hook_path(char const* const hook_name) +{ + char* path; + char* xdg_config_dir = getenv("XDG_CONFIG_HOME"); + if (xdg_config_dir) + asprintf(&path, "%s/miix-wlr/hooks/%s-hook", xdg_config_dir, hook_name); + else + asprintf(&path, + "%s/.config/miix-wlr/hooks/%s-hook", + getenv("HOME"), + hook_name); + return path; +} + +static void on_basestation_connected() +{ + printf("Basestation connected\n"); + + char* hook_path = get_hook_path("basestation-connected"); + + if (access(hook_path, X_OK) != 0) { + fprintf(stderr, "Couldn't read or execute hook at %s\n", hook_path); + free(hook_path); + return; + } + + pid_t pid = fork(); + + if (pid < 0) { + // Error + fprintf(stderr, "Unable to run hook script!\n"); + perror("fork"); + } else if (pid == 0) { + // In the child + char* argv[] = {hook_path, 0}; + execve(hook_path, argv, environ); + exit(-1); + } else { + free(hook_path); + } +} + +static void on_basestation_disconnected() +{ + printf("Basestation disconnected\n"); + + char* hook_path = get_hook_path("basestation-disconnected"); + + if (access(hook_path, X_OK) != 0) { + // Hook is innaccessible + fprintf(stderr, "Couldn't read or execute hook at %s\n", hook_path); + free(hook_path); + return; + } + + pid_t pid = fork(); + + if (pid < 0) { + // Error + fprintf(stderr, "Unable to run hook script!\n"); + perror("fork"); + } else if (pid == 0) { + // In the child + char* argv[] = {hook_path, 0}; + execve(hook_path, argv, environ); + exit(-1); + } else { + free(hook_path); + } +} + static enum accel_rotation last_accel_rotation = ACCEL_ROTATION_NO_CHANGE; int main(int, char**) @@ -35,6 +111,10 @@ int main(int, char**) struct usb_detector* base_station_detector = create_detector(BASESTATION_VENDOR_ID, BASESTATION_PRODUCT_ID); + base_station_detector->on_connected = &on_basestation_connected; + base_station_detector->on_disconnected = &on_basestation_disconnected; + base_station_detector->has_hotplug_callbacks = true; + struct miix_wlr_state* state = miix_wlr_init(); for (;;) { diff --git a/usb_device_detection.c b/usb_device_detection.c index f719d85..d466840 100644 --- a/usb_device_detection.c +++ b/usb_device_detection.c @@ -10,11 +10,13 @@ int hotplug_callback(struct libusb_context*, { struct usb_detector* detector = user_data; - if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) + if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) { detector->is_connected = true; - else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) + if (detector->has_hotplug_callbacks) detector->on_connected(); + } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) { detector->is_connected = false; - else + if (detector->has_hotplug_callbacks) detector->on_disconnected(); + } else printf("Unexpected USB device event %d\n", event); return 0; @@ -49,6 +51,8 @@ struct usb_detector* create_detector(uint16_t vendor_id, uint16_t product_id) detector->is_connected = false; detector->event_handler_should_exit = false; + detector->has_hotplug_callbacks = false; + if (libusb_hotplug_register_callback(detector->usb_context, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, diff --git a/usb_device_detection.h b/usb_device_detection.h index 8af8e4f..011bded 100644 --- a/usb_device_detection.h +++ b/usb_device_detection.h @@ -6,6 +6,8 @@ #include +typedef void (*hotplug_callback_f)(); + struct usb_detector { atomic_bool is_connected; @@ -14,6 +16,10 @@ struct usb_detector { struct libusb_context* usb_context; libusb_hotplug_callback_handle hotplug_handle; + + atomic_bool has_hotplug_callbacks; + hotplug_callback_f on_connected; + hotplug_callback_f on_disconnected; }; struct usb_detector* create_detector(uint16_t vendor_id, uint16_t product_id);