1
0
forked from drath/libratbag

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)
This commit is contained in:
Thomas H.P. Andersen
2020-09-29 00:25:42 +02:00
parent e570e29a1e
commit 9d30ec5437
6 changed files with 169 additions and 38 deletions

View File

@@ -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

View File

@@ -3,3 +3,7 @@ Name=Glorious Model D
DeviceMatch=usb:258a:0033
Driver=sinowealth
[Driver/sinowealth]
Buttons=6
Leds=2
DpiRange=100:12000@100

View File

@@ -3,3 +3,7 @@ Name=Glorious Model O
DeviceMatch=usb:258a:0036
Driver=sinowealth
[Driver/sinowealth]
Buttons=6
Leds=2
DpiRange=100:12000@100

View File

@@ -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<<resolution->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<<resolution->index;
config->dpi_count++;

View File

@@ -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;
}

View File

@@ -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);