forked from drath/libratbag
Add list of report rates to the resolutions
Same blueprint as the list of DPI values Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
committed by
Benjamin Tissoires
parent
74a5551a8d
commit
ec7bb2f63a
12
doc/dbus.rst
12
doc/dbus.rst
@@ -292,6 +292,18 @@ org.freedesktop.ratbag1.Resolution
|
||||
capability, changing the report rate on one resolution will
|
||||
change the report rate on all resolutions.
|
||||
|
||||
.. js:attribute:: ReportRates
|
||||
|
||||
:type: au
|
||||
:flags: read-write, constant
|
||||
|
||||
A list of permitted report rates. Values in this list may be used
|
||||
in the :js:attr:`ReportRate` property. This list is always sorted
|
||||
ascending, the lowest report rate is the first item in the list.
|
||||
|
||||
This list may be empty if the device does not support reading and/or
|
||||
writing to resolutions.
|
||||
|
||||
.. js:function:: SetDefault() → ()
|
||||
|
||||
Set this resolution to be the default
|
||||
|
||||
@@ -296,6 +296,39 @@ ratbagd_resolution_get_report_rate(sd_bus *bus,
|
||||
return sd_bus_message_append(reply, "u", rate);
|
||||
}
|
||||
|
||||
static int
|
||||
ratbagd_resolution_get_report_rates(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_resolution *resolution = userdata;
|
||||
struct ratbag_resolution *lib_resolution = resolution->lib_resolution;
|
||||
unsigned int rates[5];
|
||||
unsigned int nrates = ARRAY_LENGTH(rates);
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "u");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
nrates = ratbag_resolution_get_report_rate_list(lib_resolution,
|
||||
rates, nrates);
|
||||
assert(nrates <= ARRAY_LENGTH(rates));
|
||||
|
||||
for (unsigned int i = 0; i < nrates; i++) {
|
||||
r = sd_bus_message_append(reply, "u", rates[i]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ratbagd_resolution_set_report_rate(sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -348,6 +381,7 @@ const sd_bus_vtable ratbagd_resolution_vtable[] = {
|
||||
ratbagd_resolution_get_report_rate,
|
||||
ratbagd_resolution_set_report_rate, 0,
|
||||
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("ReportRates", "au", ratbagd_resolution_get_report_rates, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_METHOD("SetActive", "", "u", ratbagd_resolution_set_active, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetDefault", "", "u", ratbagd_resolution_set_default, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_VTABLE_END,
|
||||
|
||||
@@ -430,6 +430,7 @@ etekcity_read_profile(struct ratbag_profile *profile)
|
||||
unsigned int report_rate;
|
||||
int dpi_x, dpi_y, hz;
|
||||
int rc;
|
||||
unsigned int report_rates[] = { 125, 250, 500, 1000 };
|
||||
|
||||
assert(profile->index <= ETEKCITY_PROFILE_MAX);
|
||||
|
||||
@@ -446,12 +447,9 @@ etekcity_read_profile(struct ratbag_profile *profile)
|
||||
return;
|
||||
|
||||
/* first retrieve the report rate, it is set per profile */
|
||||
switch (setting_report->report_rate) {
|
||||
case 0x00: report_rate = 125; break;
|
||||
case 0x01: report_rate = 250; break;
|
||||
case 0x02: report_rate = 500; break;
|
||||
case 0x03: report_rate = 1000; break;
|
||||
default:
|
||||
if (setting_report->report_rate < ARRAY_LENGTH(report_rates)) {
|
||||
report_rate = report_rates[setting_report->report_rate];
|
||||
} else {
|
||||
log_error(device->ratbag,
|
||||
"error while reading the report rate of the mouse (0x%02x)\n",
|
||||
buf[26]);
|
||||
@@ -473,6 +471,9 @@ etekcity_read_profile(struct ratbag_profile *profile)
|
||||
ratbag_resolution_set_cap(resolution,
|
||||
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
|
||||
resolution->is_active = (resolution->index == setting_report->current_dpi);
|
||||
|
||||
ratbag_resolution_set_report_rate_list(resolution, report_rates,
|
||||
ARRAY_LENGTH(report_rates));
|
||||
}
|
||||
|
||||
ratbag_profile_for_each_button(profile, button)
|
||||
|
||||
@@ -988,6 +988,8 @@ gskill_read_resolutions(struct ratbag_profile *profile,
|
||||
|
||||
for (i = 0; i < report->dpi_num; i++) {
|
||||
_cleanup_resolution_ struct ratbag_resolution *resolution;
|
||||
unsigned int rates[] = { 500, 1000 }; /* let's assume that is true */
|
||||
|
||||
dpi_x = report->dpi_levels[i].x * GSKILL_DPI_UNIT;
|
||||
dpi_y = report->dpi_levels[i].y * GSKILL_DPI_UNIT;
|
||||
|
||||
@@ -1001,6 +1003,8 @@ gskill_read_resolutions(struct ratbag_profile *profile,
|
||||
|
||||
ratbag_resolution_set_dpi_list_from_range(resolution,
|
||||
GSKILL_MIN_DPI, GSKILL_MAX_DPI);
|
||||
ratbag_resolution_set_report_rate_list(resolution, rates,
|
||||
ARRAY_LENGTH(rates));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -397,6 +397,10 @@ hidpp10drv_read_profile(struct ratbag_profile *profile)
|
||||
uint16_t xres, yres;
|
||||
uint8_t idx;
|
||||
|
||||
/* 0x64 USB_REFRESH_RATE has time between reports in ms. so let's
|
||||
* assume the 1000/500/250 rates exist on the devices */
|
||||
unsigned int rates[] = {250, 500, 1000};
|
||||
|
||||
drv_data = ratbag_get_drv_data(device);
|
||||
hidpp10 = drv_data->dev;
|
||||
rc = hidpp10_get_profile(hidpp10, profile->index, &p);
|
||||
@@ -449,6 +453,9 @@ hidpp10drv_read_profile(struct ratbag_profile *profile)
|
||||
|
||||
ratbag_resolution_set_dpi_list(res, dpis, hidpp10->dpi_count);
|
||||
}
|
||||
|
||||
ratbag_resolution_set_report_rate_list(res, rates,
|
||||
ARRAY_LENGTH(rates));
|
||||
}
|
||||
|
||||
ratbag_profile_for_each_button(profile, button)
|
||||
|
||||
@@ -669,6 +669,7 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
|
||||
ratbag_profile_for_each_resolution(profile, res) {
|
||||
struct hidpp20_sensor *sensor;
|
||||
unsigned int rate = 500; /* let's assume that one is just present */
|
||||
|
||||
/* We only look at the first sensor. Multiple
|
||||
* sensors is too niche to care about right now */
|
||||
@@ -679,6 +680,7 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
ratbag_resolution_set_dpi_list_from_range(res,
|
||||
sensor->dpi_min,
|
||||
sensor->dpi_max);
|
||||
ratbag_resolution_set_report_rate_list(res, &rate, 1);
|
||||
|
||||
/* FIXME: we mark all resolutions as active because
|
||||
* they are from different sensors */
|
||||
@@ -866,6 +868,7 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile)
|
||||
|
||||
ratbag_profile_for_each_resolution(profile, res) {
|
||||
struct hidpp20_sensor *sensor;
|
||||
unsigned int rate = p->report_rate;
|
||||
|
||||
/* We only look at the first sensor. Multiple
|
||||
* sensors is too niche to care about right now */
|
||||
@@ -888,7 +891,7 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile)
|
||||
ratbag_resolution_set_dpi_list_from_range(res,
|
||||
sensor->dpi_min,
|
||||
sensor->dpi_max);
|
||||
|
||||
ratbag_resolution_set_report_rate_list(res, &rate, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -396,6 +396,7 @@ logitech_g300_read_profile(struct ratbag_profile *profile)
|
||||
ratbag_resolution_set_dpi_list_from_range(resolution,
|
||||
LOGITECH_G300_DPI_MIN,
|
||||
LOGITECH_G300_DPI_MAX);
|
||||
ratbag_resolution_set_report_rate_list(resolution, &hz, 1);
|
||||
}
|
||||
|
||||
ratbag_profile_for_each_button(profile, button)
|
||||
|
||||
@@ -704,6 +704,7 @@ roccat_read_profile(struct ratbag_profile *profile)
|
||||
unsigned int report_rate;
|
||||
int dpi_x, dpi_y, hz;
|
||||
int rc;
|
||||
unsigned int report_rates[] = { 125, 250, 500, 1000 };
|
||||
|
||||
assert(profile->index <= ROCCAT_PROFILE_MAX);
|
||||
|
||||
@@ -720,12 +721,9 @@ roccat_read_profile(struct ratbag_profile *profile)
|
||||
return;
|
||||
|
||||
/* first retrieve the report rate, it is set per profile */
|
||||
switch (setting_report->report_rate) {
|
||||
case 0x00: report_rate = 125; break;
|
||||
case 0x01: report_rate = 250; break;
|
||||
case 0x02: report_rate = 500; break;
|
||||
case 0x03: report_rate = 1000; break;
|
||||
default:
|
||||
if (setting_report->report_rate < ARRAY_LENGTH(report_rates)) {
|
||||
report_rate = report_rates[setting_report->report_rate];
|
||||
} else {
|
||||
log_error(device->ratbag,
|
||||
"error while reading the report rate of the mouse (0x%02x)\n",
|
||||
buf[26]);
|
||||
@@ -747,6 +745,9 @@ roccat_read_profile(struct ratbag_profile *profile)
|
||||
ratbag_resolution_set_cap(resolution,
|
||||
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
|
||||
resolution->is_active = (resolution->index == setting_report->current_dpi);
|
||||
|
||||
ratbag_resolution_set_report_rate_list(resolution, report_rates,
|
||||
ARRAY_LENGTH(report_rates));
|
||||
}
|
||||
|
||||
ratbag_profile_for_each_button(profile, button)
|
||||
|
||||
@@ -191,6 +191,7 @@ test_read_profile(struct ratbag_profile *profile)
|
||||
|
||||
for (i = 0; i < d->num_resolutions; i++) {
|
||||
_cleanup_resolution_ struct ratbag_resolution *res;
|
||||
size_t nrates = 0;
|
||||
|
||||
r = &p->resolutions[i];
|
||||
|
||||
@@ -201,6 +202,17 @@ test_read_profile(struct ratbag_profile *profile)
|
||||
ratbag_resolution_set_dpi_list_from_range(res,
|
||||
r0->dpi_min,
|
||||
r0->dpi_max);
|
||||
|
||||
for (size_t r = 0; r < ARRAY_LENGTH(r0->report_rates); r++) {
|
||||
if (r0->report_rates[r] > 0)
|
||||
nrates++;
|
||||
}
|
||||
|
||||
if (nrates > 0)
|
||||
ratbag_resolution_set_report_rate_list(res,
|
||||
r0->report_rates,
|
||||
nrates);
|
||||
|
||||
res->is_active = r->active;
|
||||
if (r->active)
|
||||
active_set = true;
|
||||
|
||||
@@ -261,6 +261,10 @@ struct ratbag_resolution {
|
||||
unsigned int dpi_x; /**< x resolution in dpi */
|
||||
unsigned int dpi_y; /**< y resolution in dpi */
|
||||
unsigned int hz; /**< report rate in Hz */
|
||||
|
||||
unsigned int rates[5];
|
||||
size_t nrates;
|
||||
|
||||
bool is_active;
|
||||
bool is_default;
|
||||
uint32_t capabilities;
|
||||
@@ -528,6 +532,22 @@ ratbag_resolution_set_dpi_list(struct ratbag_resolution *res,
|
||||
res->ndpis = ndpis;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ratbag_resolution_set_report_rate_list(struct ratbag_resolution *res,
|
||||
unsigned int *rates,
|
||||
size_t nrates)
|
||||
{
|
||||
assert(nrates <= ARRAY_LENGTH(res->rates));
|
||||
_Static_assert(sizeof(*rates) == sizeof(*res->rates), "Mismatching size");
|
||||
|
||||
for (size_t i = 0; i < nrates; i++) {
|
||||
res->rates[i] = rates[i];
|
||||
if (i > 0)
|
||||
assert(rates[i] > rates[i - 1]);
|
||||
}
|
||||
res->nrates = nrates;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ratbag_resolution_set_cap(struct ratbag_resolution *res,
|
||||
enum ratbag_resolution_capability cap)
|
||||
|
||||
@@ -57,6 +57,7 @@ struct ratbag_test_resolution {
|
||||
uint32_t caps;
|
||||
|
||||
int dpi_min, dpi_max;
|
||||
unsigned int report_rates[5];
|
||||
};
|
||||
|
||||
struct ratbag_test_color {
|
||||
|
||||
@@ -1158,6 +1158,24 @@ ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution)
|
||||
return resolution->hz;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT size_t
|
||||
ratbag_resolution_get_report_rate_list(struct ratbag_resolution *resolution,
|
||||
unsigned int *rates,
|
||||
size_t nrates)
|
||||
{
|
||||
_Static_assert(sizeof(*rates) == sizeof(*resolution->rates), "type mismatch");
|
||||
|
||||
assert(nrates > 0);
|
||||
|
||||
if (resolution->nrates == 0)
|
||||
return 0;
|
||||
|
||||
memcpy(rates, resolution->rates,
|
||||
sizeof(unsigned int) * min(nrates, resolution->nrates));
|
||||
|
||||
return resolution->nrates;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_resolution_is_active(const struct ratbag_resolution *resolution)
|
||||
{
|
||||
|
||||
@@ -936,6 +936,29 @@ ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
|
||||
int
|
||||
ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Get the number of report rates in Hz available for this resolution.
|
||||
* The list of report rates is sorted in ascending order but may be filtered
|
||||
* by libratbag and does not necessarily reflect all report rates supported by
|
||||
* the physical device.
|
||||
*
|
||||
* This function writes at most nrates values but returns the number of
|
||||
* report rates available on this resolution. In other words, if it returns a
|
||||
* number larger than nrates, call it again with an array the size of the
|
||||
* return value.
|
||||
*
|
||||
* @param[out] rates Set to the supported report rates in ascending order
|
||||
* @param[in] nrates The number of elements in resolutions
|
||||
*
|
||||
* @return The number of valid items in rates. If the returned value
|
||||
* is larger than nrates, the list was truncated.
|
||||
*/
|
||||
size_t
|
||||
ratbag_resolution_get_report_rate_list(struct ratbag_resolution *resolution,
|
||||
unsigned int *rates,
|
||||
size_t nrates);
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
|
||||
@@ -598,6 +598,11 @@ class RatbagdResolution(_RatbagdDBus):
|
||||
"""The list of supported DPI values"""
|
||||
return self._get_dbus_property("Resolutions")
|
||||
|
||||
@GObject.Property
|
||||
def report_rates(self):
|
||||
"""The list of supported report rates"""
|
||||
return self._get_dbus_property("ReportRates")
|
||||
|
||||
@GObject.Property
|
||||
def is_active(self):
|
||||
"""True if this is the currently active resolution, False
|
||||
|
||||
Reference in New Issue
Block a user