From 9d30ec54376ff19fdb9ed2aaafb56e9bcdb19eda Mon Sep 17 00:00:00 2001 From: "Thomas H.P. Andersen" Date: Tue, 29 Sep 2020 00:25:42 +0200 Subject: [PATCH] sinowealth: read device-specific from .device file This moves device-specific specifications to the .device files. The number of LEDs and buttons varies as well as sensor (dpi specs) --- data/devices/dream-machines-dm5-blink.device | 4 + data/devices/glorious-model-d.device | 4 + data/devices/glorious-model-o.device | 4 + src/driver-sinowealth.c | 112 +++++++++++++------ src/libratbag-data.c | 68 ++++++++++- src/libratbag-data.h | 15 +++ 6 files changed, 169 insertions(+), 38 deletions(-) diff --git a/data/devices/dream-machines-dm5-blink.device b/data/devices/dream-machines-dm5-blink.device index a4e411ee..084f14b0 100644 --- a/data/devices/dream-machines-dm5-blink.device +++ b/data/devices/dream-machines-dm5-blink.device @@ -3,3 +3,7 @@ Name=Dream Machines DM5 Blink DeviceMatch=usb:258a:0027 Driver=sinowealth +[Driver/sinowealth] +Buttons=8 +Leds=1 +DpiRange=100:16000@100 diff --git a/data/devices/glorious-model-d.device b/data/devices/glorious-model-d.device index 7b8a0b8b..14a59ec1 100644 --- a/data/devices/glorious-model-d.device +++ b/data/devices/glorious-model-d.device @@ -3,3 +3,7 @@ Name=Glorious Model D DeviceMatch=usb:258a:0033 Driver=sinowealth +[Driver/sinowealth] +Buttons=6 +Leds=2 +DpiRange=100:12000@100 \ No newline at end of file diff --git a/data/devices/glorious-model-o.device b/data/devices/glorious-model-o.device index 022ceffc..7a0d5787 100644 --- a/data/devices/glorious-model-o.device +++ b/data/devices/glorious-model-o.device @@ -3,3 +3,7 @@ Name=Glorious Model O DeviceMatch=usb:258a:0036 Driver=sinowealth +[Driver/sinowealth] +Buttons=6 +Leds=2 +DpiRange=100:12000@100 \ No newline at end of file diff --git a/src/driver-sinowealth.c b/src/driver-sinowealth.c index 915e3b52..6d62a075 100644 --- a/src/driver-sinowealth.c +++ b/src/driver-sinowealth.c @@ -23,6 +23,7 @@ #include "libratbag-private.h" #include "libratbag-hidraw.h" +#include "libratbag-data.h" #define SINOWEALTH_REPORT_ID_CONFIG 0x4 #define SINOWEALTH_REPORT_ID_CMD 0x5 @@ -33,11 +34,6 @@ #define SINOWEALTH_XY_INDEPENDENT 0x80 -/* The PC software only goes down to 400, but the PMW3360 doesn't care */ -#define SINOWEALTH_DPI_MIN 100 -#define SINOWEALTH_DPI_MAX 12000 -#define SINOWEALTH_DPI_STEP 100 - /* other models might have up to eight */ #define SINOWEALTH_NUM_DPIS 6 @@ -137,19 +133,39 @@ _Static_assert(sizeof(struct sinowealth_config_report) == SINOWEALTH_CONFIG_SIZE struct sinowealth_data { /* this is kinda unnecessary at this time, but all the other drivers do it too ;) */ struct sinowealth_config_report config; + bool is_sensor_3360; }; static int -sinowealth_raw_to_dpi(int raw) +sinowealth_raw_to_dpi(struct ratbag_device *device, int raw) { - return (raw + 1) * 100; + struct sinowealth_data *drv_data = device->drv_data; + int dpi; + + if (drv_data->is_sensor_3360) + dpi = (raw + 1) * 100; + else + dpi = raw * 100; + + return dpi; } static int -sinowealth_dpi_to_raw(int dpi) +sinowealth_dpi_to_raw(struct ratbag_device *device, unsigned int dpi) { - assert(dpi >= SINOWEALTH_DPI_MIN && dpi <= SINOWEALTH_DPI_MAX); - return dpi / 100 - 1; + struct sinowealth_data *drv_data = device->drv_data; + struct dpi_range *dpirange = NULL; + int raw; + + dpirange = ratbag_device_data_sinowealth_get_dpi_range(device->data); + assert(dpi >= dpirange->min && dpi <= dpirange->max); + + if (drv_data->is_sensor_3360) + raw = dpi / 100 - 1; + else + raw = dpi / 100; + + return raw; } static struct ratbag_color @@ -266,10 +282,10 @@ sinowealth_read_profile(struct ratbag_profile *profile) ratbag_profile_for_each_resolution(profile, resolution) { if (config->config & SINOWEALTH_XY_INDEPENDENT) { - resolution->dpi_x = sinowealth_raw_to_dpi(config->dpi[resolution->index * 2]); - resolution->dpi_y = sinowealth_raw_to_dpi(config->dpi[resolution->index * 2 + 1]); + resolution->dpi_x = sinowealth_raw_to_dpi(device, config->dpi[resolution->index * 2]); + resolution->dpi_y = sinowealth_raw_to_dpi(device, config->dpi[resolution->index * 2 + 1]); } else { - resolution->dpi_x = sinowealth_raw_to_dpi(config->dpi[resolution->index]); + resolution->dpi_x = sinowealth_raw_to_dpi(device, config->dpi[resolution->index]); resolution->dpi_y = resolution->dpi_x; } if (config->dpi_enabled & (1<index)) { @@ -320,37 +336,59 @@ sinowealth_init_profile(struct ratbag_device *device) struct ratbag_profile *profile; struct ratbag_resolution *resolution; struct ratbag_led *led; - /* number of DPIs = all DPIs from min to max (inclusive) and "0 DPI" as a special value - * to signal a disabled DPI step. - */ - int num_dpis = (SINOWEALTH_DPI_MAX - SINOWEALTH_DPI_MIN) / SINOWEALTH_DPI_STEP + 2; - unsigned int dpis[num_dpis]; + struct sinowealth_data *drv_data = device->drv_data; + struct dpi_range *dpirange = NULL; + int button_count, led_count; + dpirange = ratbag_device_data_sinowealth_get_dpi_range(device->data); + button_count = ratbag_device_data_sinowealth_get_button_count(device->data); + led_count = ratbag_device_data_sinowealth_get_led_count(device->data); /* TODO: Button remapping */ - ratbag_device_init_profiles(device, 1, SINOWEALTH_NUM_DPIS, 0, 1); + + if (!dpirange) + { + log_error(device->ratbag, "DpiRange must be defined in .device file\n"); + } + + if (button_count < 0) + { + log_error(device->ratbag, "Button count must be defined in .device file\n"); + button_count = 0; + } + + if (led_count < 0) + { + log_error(device->ratbag, "Led count must be defined in .device file\n"); + led_count = 0; + } + + drv_data->is_sensor_3360 = dpirange->max == 12000; + + ratbag_device_init_profiles(device, 1, SINOWEALTH_NUM_DPIS, button_count, led_count); profile = ratbag_device_get_profile(device, 0); - /* Generate DPI list */ - dpis[0] = 0; /* 0 DPI = disabled */ - for (int i = 1; i < num_dpis; i++) { - dpis[i] = SINOWEALTH_DPI_MIN + (i - 1) * SINOWEALTH_DPI_STEP; - } - ratbag_profile_for_each_resolution(profile, resolution) { - ratbag_resolution_set_dpi_list(resolution, dpis, num_dpis); + ratbag_resolution_set_dpi_list_from_range(resolution, + dpirange->min, + dpirange->max); ratbag_resolution_set_cap(resolution, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); } /* Set up LED capabilities */ - led = ratbag_profile_get_led(profile, 0); - led->type = RATBAG_LED_TYPE_SIDE; - led->colordepth = RATBAG_LED_COLORDEPTH_RGB_888; - ratbag_led_set_mode_capability(led, RATBAG_LED_OFF); - ratbag_led_set_mode_capability(led, RATBAG_LED_ON); - ratbag_led_set_mode_capability(led, RATBAG_LED_CYCLE); - ratbag_led_set_mode_capability(led, RATBAG_LED_BREATHING); - ratbag_led_unref(led); + ratbag_profile_for_each_led(profile, led) { + if (led->index == 0) { + led->type = RATBAG_LED_TYPE_SIDE; + led->colordepth = RATBAG_LED_COLORDEPTH_RGB_888; + ratbag_led_set_mode_capability(led, RATBAG_LED_OFF); + ratbag_led_set_mode_capability(led, RATBAG_LED_ON); + ratbag_led_set_mode_capability(led, RATBAG_LED_CYCLE); + ratbag_led_set_mode_capability(led, RATBAG_LED_BREATHING); + } else { + led->type = RATBAG_LED_TYPE_DPI; + led->colordepth = RATBAG_LED_COLORDEPTH_RGB_888; + } + } ratbag_profile_unref(profile); } @@ -418,10 +456,10 @@ sinowealth_commit(struct ratbag_device *device) if (!resolution->dpi_x || !resolution->dpi_y) continue; if (config->config & SINOWEALTH_XY_INDEPENDENT) { - config->dpi[resolution->index * 2] = sinowealth_dpi_to_raw(resolution->dpi_x); - config->dpi[resolution->index * 2 + 1] = sinowealth_dpi_to_raw(resolution->dpi_y); + config->dpi[resolution->index * 2] = sinowealth_dpi_to_raw(device, resolution->dpi_x); + config->dpi[resolution->index * 2 + 1] = sinowealth_dpi_to_raw(device, resolution->dpi_y); } else { - config->dpi[resolution->index] = sinowealth_dpi_to_raw(resolution->dpi_x); + config->dpi[resolution->index] = sinowealth_dpi_to_raw(device, resolution->dpi_x); } dpi_enabled |= 1<index; config->dpi_count++; diff --git a/src/libratbag-data.c b/src/libratbag-data.c index 9f137b11..06340a54 100644 --- a/src/libratbag-data.c +++ b/src/libratbag-data.c @@ -82,6 +82,12 @@ struct data_steelseries { int short_button; }; +struct data_sinowealth { + int button_count; + int led_count; + struct dpi_range *dpi_range; +}; + struct ratbag_device_data { int refcount; char *name; @@ -93,6 +99,7 @@ struct ratbag_device_data { struct data_hidpp20 hidpp20; struct data_hidpp10 hidpp10; struct data_steelseries steelseries; + struct data_sinowealth sinowealth; }; enum ratbag_led_type led_types[20]; @@ -254,6 +261,41 @@ init_data_steelseries(struct ratbag *ratbag, g_error_free(error); } +static void +init_data_sinowealth(struct ratbag *ratbag, + GKeyFile *keyfile, + struct ratbag_device_data *data) +{ + const char *group = "Driver/sinowealth"; + GError *error = NULL; + _cleanup_(freep) char *str = NULL; + int num; + + data->sinowealth.button_count = -1; + data->sinowealth.led_count = -1; + + num = g_key_file_get_integer(keyfile, group, "Buttons", &error); + if (num != 0 || !error) + data->sinowealth.button_count = num; + if (error) + g_error_free(error); + + error = NULL; + num = g_key_file_get_integer(keyfile, group, "Leds", &error); + if (num > 0 || !error) + data->sinowealth.led_count = num; + if (error) + g_error_free(error); + + error = NULL; + + str = g_key_file_get_string(keyfile, group, "DpiRange", NULL); + if (str) + data->sinowealth.dpi_range = dpi_range_from_string(str); + error = NULL; + +} + static const struct driver_map { enum driver map; const char *driver; @@ -269,7 +311,7 @@ static const struct driver_map { { LOGITECH_G300, "logitech_g300", NULL}, { LOGITECH_G600, "logitech_g600", NULL}, { STEELSERIES, "steelseries", init_data_steelseries }, - { SINOWEALTH, "sinowealth", NULL }, + { SINOWEALTH, "sinowealth", init_data_sinowealth }, { SINOWEALTH_NUBWO, "sinowealth_nubwo", NULL}, }; @@ -670,3 +712,27 @@ ratbag_device_data_steelseries_get_short_button(const struct ratbag_device_data return data->steelseries.short_button; } + +int +ratbag_device_data_sinowealth_get_button_count(const struct ratbag_device_data *data) +{ + assert(data->drivertype == SINOWEALTH); + + return data->sinowealth.button_count; +} + +int +ratbag_device_data_sinowealth_get_led_count(const struct ratbag_device_data *data) +{ + assert(data->drivertype == SINOWEALTH); + + return data->sinowealth.led_count; +} + +struct dpi_range * +ratbag_device_data_sinowealth_get_dpi_range(const struct ratbag_device_data *data) +{ + assert(data->drivertype == SINOWEALTH); + + return data->sinowealth.dpi_range; +} diff --git a/src/libratbag-data.h b/src/libratbag-data.h index ffb4b266..cce1bb36 100644 --- a/src/libratbag-data.h +++ b/src/libratbag-data.h @@ -120,3 +120,18 @@ ratbag_device_data_steelseries_get_mono_led(const struct ratbag_device_data *dat int ratbag_device_data_steelseries_get_short_button(const struct ratbag_device_data *data); + +/** + * @return The button count or -1 if not set + */ +int +ratbag_device_data_sinowealth_get_button_count(const struct ratbag_device_data *data); + +/** + * @return The led count or -1 if not set + */ +int +ratbag_device_data_sinowealth_get_led_count(const struct ratbag_device_data *data); + +struct dpi_range * +ratbag_device_data_sinowealth_get_dpi_range(const struct ratbag_device_data *data);