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:
Peter Hutterer
2017-10-16 17:49:26 +10:00
committed by Benjamin Tissoires
parent 74a5551a8d
commit ec7bb2f63a
14 changed files with 155 additions and 13 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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