daemon: Added support for multiple device configurations

This commit is contained in:
zeGolem 2023-08-27 20:39:55 +02:00
parent 9856450db7
commit 42c8902fa8
2 changed files with 138 additions and 30 deletions

View file

@ -0,0 +1,51 @@
#pragma once
#include <stdint.h>
struct device_information {
char const* const device_name;
bool screen_rotation_supported;
char const* const target_output;
char const* const target_motion_sensor;
enum wl_output_transform const sensor_to_output_rotation[4];
bool basestation_detection_supported;
uint16_t const basestation_vendor_id;
uint16_t const basestation_product_id;
};
static struct device_information DEVICE_INFORMATION_GENERIC = {
.device_name = "generic",
.screen_rotation_supported = true,
.target_output = "eDP-1",
.target_motion_sensor = "/sys/bus/iio/devices/iio:device0",
.sensor_to_output_rotation =
{
[ACCEL_ROTATION_0DEG] = WL_OUTPUT_TRANSFORM_NORMAL,
[ACCEL_ROTATION_90DEG] = WL_OUTPUT_TRANSFORM_90,
[ACCEL_ROTATION_180DEG] = WL_OUTPUT_TRANSFORM_180,
[ACCEL_ROTATION_270DEG] = WL_OUTPUT_TRANSFORM_270,
},
.basestation_detection_supported = false,
.basestation_vendor_id = 0,
.basestation_product_id = 0,
};
static struct device_information DEVICE_INFOS[] = {
{
.device_name = "lenovo-miix-320-10icr",
.screen_rotation_supported = true,
.target_output = "DSI-1",
.target_motion_sensor = "/sys/bus/iio/devices/iio:device0",
.sensor_to_output_rotation =
{
[ACCEL_ROTATION_0DEG] = WL_OUTPUT_TRANSFORM_270,
[ACCEL_ROTATION_90DEG] = WL_OUTPUT_TRANSFORM_NORMAL,
[ACCEL_ROTATION_180DEG] = WL_OUTPUT_TRANSFORM_90,
[ACCEL_ROTATION_270DEG] = WL_OUTPUT_TRANSFORM_180,
},
.basestation_detection_supported = true,
.basestation_vendor_id = 0x048d,
.basestation_product_id = 0x8911,
},
};

View file

@ -4,6 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libusb-1.0/libusb.h>
@ -11,27 +12,37 @@
#include "accel_monitor.h"
#include "output_manager.h"
#include "usb_device_detection.h"
#include "device_information.h"
static enum wl_output_transform const SENSOR_TO_OUTPUT_ROTATION[] = {
[ACCEL_ROTATION_0DEG] = WL_OUTPUT_TRANSFORM_270,
[ACCEL_ROTATION_90DEG] = WL_OUTPUT_TRANSFORM_NORMAL,
[ACCEL_ROTATION_180DEG] = WL_OUTPUT_TRANSFORM_90,
[ACCEL_ROTATION_270DEG] = WL_OUTPUT_TRANSFORM_180,
};
static struct device_information get_device_info_for_name(
char const* const device_name)
{
if (strcmp(device_name, "generic") == 0) {
fprintf(
stderr,
"WARNING: Using a 'generic' device. This may not work properly.\n");
return DEVICE_INFORMATION_GENERIC;
}
static char const* const DEFAULT_OUTPUT = "DSI-1";
static char const* const DEFAULT_MOTION_SENSOR =
"/sys/bus/iio/devices/iio:device0";
static size_t const device_info_count =
sizeof(DEVICE_INFOS) / sizeof(*DEVICE_INFOS);
for (size_t i = 0; i < device_info_count; ++i) {
struct device_information current = DEVICE_INFOS[i];
if (strcmp(current.device_name, device_name) == 0) return current;
}
static uint16_t const BASESTATION_VENDOR_ID = 0x048d;
static uint16_t const BASESTATION_PRODUCT_ID = 0x8911;
fprintf(stderr, "No matching configuration for '%s'.\n", device_name);
return DEVICE_INFORMATION_GENERIC;
}
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/convertablet/hooks/%s-hook", xdg_config_dir, hook_name);
asprintf(
&path, "%s/convertablet/hooks/%s-hook", xdg_config_dir, hook_name);
else
asprintf(&path,
"%s/.config/convertablet/hooks/%s-hook",
@ -99,25 +110,65 @@ static void on_basestation_disconnected()
static enum accel_rotation last_accel_rotation = ACCEL_ROTATION_NO_CHANGE;
int main(int, char**)
int main(int argc, char** argv)
{
struct accel_monitor* monitor = accel_start_monitor(DEFAULT_MOTION_SENSOR);
if (!monitor) {
fprintf(stderr, "Failed to start iio motion monitoring\n");
if (argc < 2) {
fprintf(stderr,
"No device specified! Please specify your device's name or use "
"'generic' for sane defaults.\n");
fprintf(stderr, "\tUsage: %s <device name>\n", argv[0]);
fprintf(stderr, "\t %s list-devices \n", argv[0]);
return -1;
}
struct usb_detector* base_station_detector =
create_detector(BASESTATION_VENDOR_ID, BASESTATION_PRODUCT_ID);
if (strcmp(argv[1], "list-devices") == 0) {
printf("Device names:\n");
static size_t const device_info_count =
sizeof(DEVICE_INFOS) / sizeof(*DEVICE_INFOS);
for (size_t i = 0; i < device_info_count; ++i)
printf("\t- %s\n", DEVICE_INFOS[i].device_name);
return 0;
}
base_station_detector->on_connected = &on_basestation_connected;
base_station_detector->on_disconnected = &on_basestation_disconnected;
base_station_detector->has_hotplug_callbacks = true;
struct device_information device_info = get_device_info_for_name(argv[1]);
struct miix_wlr_state* state = miix_wlr_init();
struct accel_monitor* monitor = 0;
struct miix_wlr_state* state = 0;
if (device_info.screen_rotation_supported) {
monitor = accel_start_monitor(device_info.target_motion_sensor);
if (!monitor) {
fprintf(stderr, "Failed to start iio motion monitoring\n");
return -1;
}
state = miix_wlr_init();
if (!state) {
fprintf(stderr, "Failed to connect to wayland server.\n");
return -1;
}
} else
fprintf(stderr, "Screen rotation not supported.\n");
struct usb_detector* base_station_detector = 0;
if (device_info.basestation_detection_supported) {
base_station_detector =
create_detector(device_info.basestation_vendor_id,
device_info.basestation_product_id);
if (!base_station_detector) {
fprintf(stderr, "Failed to create basestation detector.\n");
return -1;
}
base_station_detector->on_connected = &on_basestation_connected;
base_station_detector->on_disconnected = &on_basestation_disconnected;
base_station_detector->has_hotplug_callbacks = true;
} else
fprintf(stderr, "Base station detection not supported.\n");
for (;;) { // Main loop that handles the rotation detection.
// If screen rotation isn't supported, let's just do nothing.
if (!device_info.screen_rotation_supported) continue;
for (;;) {
thrd_sleep(&(struct timespec){0, 10000000UL}, NULL);
if (!monitor->data_is_ready) continue;
@ -125,8 +176,8 @@ int main(int, char**)
if (last_accel_rotation != ACCEL_ROTATION_0DEG) {
miix_wlr_head_set_transform(
state,
DEFAULT_OUTPUT,
SENSOR_TO_OUTPUT_ROTATION[ACCEL_ROTATION_0DEG]);
device_info.target_output,
device_info.sensor_to_output_rotation[ACCEL_ROTATION_0DEG]);
last_accel_rotation = ACCEL_ROTATION_0DEG;
}
continue;
@ -137,11 +188,17 @@ int main(int, char**)
rotation == last_accel_rotation)
continue;
miix_wlr_head_set_transform(
state, DEFAULT_OUTPUT, SENSOR_TO_OUTPUT_ROTATION[rotation]);
state,
device_info.target_output,
device_info.sensor_to_output_rotation[rotation]);
last_accel_rotation = rotation;
}
accel_stop_monitor(monitor);
destroy_detector(base_station_detector);
miix_wlr_cleanup(state);
if (device_info.screen_rotation_supported) {
accel_stop_monitor(monitor);
miix_wlr_cleanup(state);
}
if (device_info.basestation_detection_supported)
destroy_detector(base_station_detector);
}