usb_device_detection: Added support for detecting basestation un/plugs

This commit is contained in:
Yuki Joou 2023-07-11 21:02:56 +02:00
parent ce96e70e66
commit 4fd8bf9bb8
4 changed files with 142 additions and 3 deletions

View file

@ -2,9 +2,9 @@
set -ex;
SOURCES="main.c output_manager.c accel_monitor.c"
SOURCES="main.c output_manager.c accel_monitor.c usb_device_detection.c"
CFLAGS="-std=c2x -Wall -Wextra -pedantic $CFLAGS"
LIBS="-lwayland-client protocol/wlr-output-management-unstable-v1.c"
LIBS="-lwayland-client -lusb-1.0 protocol/wlr-output-management-unstable-v1.c"
OUTPUT=miix-wlr
clang $CFLAGS $LIBS $SOURCES -o $OUTPUT

22
main.c
View file

@ -1,9 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include "output_manager.h"
#include <libusb-1.0/libusb.h>
#include "accel_monitor.h"
#include "output_manager.h"
#include "usb_device_detection.h"
static enum wl_output_transform const SENSOR_TO_OUTPUT_ROTATION[] = {
[ACCEL_ROTATION_0DEG] = WL_OUTPUT_TRANSFORM_270,
@ -16,6 +18,9 @@ static char const* const DEFAULT_OUTPUT = "DSI-1";
static char const* const DEFAULT_MOTION_SENSOR =
"/sys/bus/iio/devices/iio:device0";
static uint16_t const BASESTATION_VENDOR_ID = 0x048d;
static uint16_t const BASESTATION_PRODUCT_ID = 0x8911;
static enum accel_rotation last_accel_rotation = ACCEL_ROTATION_NO_CHANGE;
int main(int, char**)
@ -27,11 +32,25 @@ int main(int, char**)
return -1;
}
struct usb_detector* base_station_detector =
create_detector(BASESTATION_VENDOR_ID, BASESTATION_PRODUCT_ID);
struct miix_wlr_state* state = miix_wlr_init();
for (;;) {
if (!monitor->data_is_ready) continue;
if (base_station_detector && base_station_detector->is_connected) {
if (last_accel_rotation != ACCEL_ROTATION_0DEG) {
miix_wlr_head_set_transform(
state,
DEFAULT_OUTPUT,
SENSOR_TO_OUTPUT_ROTATION[ACCEL_ROTATION_0DEG]);
last_accel_rotation = ACCEL_ROTATION_0DEG;
}
continue;
}
enum accel_rotation rotation = accel_get_current_rotation(monitor);
if (rotation == ACCEL_ROTATION_NO_CHANGE ||
rotation == last_accel_rotation)
@ -42,5 +61,6 @@ int main(int, char**)
}
accel_stop_monitor(monitor);
destroy_detector(base_station_detector);
miix_wlr_cleanup(state);
}

99
usb_device_detection.c Normal file
View file

@ -0,0 +1,99 @@
#include "usb_device_detection.h"
#include <stdio.h>
#include <stdlib.h>
int hotplug_callback(struct libusb_context*,
struct libusb_device*,
libusb_hotplug_event event,
void* user_data)
{
struct usb_detector* detector = user_data;
if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
detector->is_connected = true;
else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
detector->is_connected = false;
else
printf("Unexpected USB device event %d\n", event);
return 0;
}
static int libusb_event_handler(void* data)
{
struct usb_detector* detector = data;
while (!detector->event_handler_should_exit) {
thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
libusb_handle_events(detector->usb_context);
}
return 0;
}
struct usb_detector* create_detector(uint16_t vendor_id, uint16_t product_id)
{
struct libusb_context* usb_context;
libusb_init(&usb_context);
if (!usb_context) {
fprintf(stderr,
"Couldn't get USB contexxt. Device detection will not work\n");
return 0;
}
struct usb_detector* detector = calloc(1, sizeof(struct usb_detector));
detector->usb_context = usb_context;
if (libusb_hotplug_register_callback(detector->usb_context,
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
LIBUSB_HOTPLUG_ENUMERATE,
vendor_id,
product_id,
LIBUSB_HOTPLUG_MATCH_ANY,
hotplug_callback,
detector,
&detector->hotplug_handle) !=
LIBUSB_SUCCESS) {
fprintf(stderr,
"Couldn't register usb hotplug listener. Device detection "
"will not work.\n");
free(detector);
return 0;
}
detector->is_connected = false;
detector->event_handler_should_exit = false;
if (thrd_create(&detector->event_handler_thread,
&libusb_event_handler,
detector) != thrd_success) {
fprintf(stderr,
"Couldn't start event handler. Device detection will not "
"work.\n");
free(detector);
return 0;
}
return detector;
}
void destroy_detector(struct usb_detector* detector)
{
libusb_hotplug_deregister_callback(detector->usb_context,
detector->hotplug_handle);
detector->event_handler_should_exit = true;
if (thrd_join(detector->event_handler_thread, 0) != thrd_success)
fprintf(stderr,
"Couldn't join with usb event handler thread, something went "
"really wrong, we likely won't exit cleanly\n");
libusb_exit(detector->usb_context);
free(detector);
}

20
usb_device_detection.h Normal file
View file

@ -0,0 +1,20 @@
#pragma once
#include <stdatomic.h>
#include <stdint.h>
#include <threads.h>
#include <libusb-1.0/libusb.h>
struct usb_detector {
atomic_bool is_connected;
atomic_bool event_handler_should_exit;
thrd_t event_handler_thread;
struct libusb_context* usb_context;
libusb_hotplug_callback_handle hotplug_handle;
};
struct usb_detector* create_detector(uint16_t vendor_id, uint16_t product_id);
void destroy_detector(struct usb_detector*);