Replace the resolutions min/max with an explicit list of dpi values

Previously, we could get a min/max value but there was no guarantee that it
any value in between would actually work on the device. Some devices have a
discrete number of resolutions (e.g. 500, 1000, 2000, 2500), most others have
at least a minimum step size (so 1234 isn't a valid dpi value).

Change the min/max to a discrete list of which resolutions are supported. This
allows a UI to adjust its interface dynamically - e.g. a combobox if there are
only 3 resolutions or a slider if there are a million of them.

This is a DBus API break

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2017-10-13 11:35:42 +10:00
committed by Benjamin Tissoires
parent a58096fade
commit f592cabcd7
12 changed files with 132 additions and 107 deletions

View File

@@ -437,7 +437,7 @@ hidpp10drv_read_profile(struct ratbag_profile *profile)
min = hidpp10_dpi_table_get_min_dpi(hidpp10);
max = hidpp10_dpi_table_get_max_dpi(hidpp10);
ratbag_resolution_set_range(res, min, max);
ratbag_resolution_set_dpi_list_from_range(res, min, max);
}
ratbag_profile_for_each_button(profile, button)

View File

@@ -667,7 +667,9 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
/* FIXME: retrieve the refresh rate */
ratbag_resolution_set_resolution(res, sensor->dpi, sensor->dpi, 0);
ratbag_resolution_set_range(res, sensor->dpi_min, sensor->dpi_max);
ratbag_resolution_set_dpi_list_from_range(res,
sensor->dpi_min,
sensor->dpi_max);
/* FIXME: we mark all resolutions as active because
* they are from different sensors */
@@ -874,7 +876,10 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile)
res->is_active = true;
}
ratbag_resolution_set_range(res, sensor->dpi_min, sensor->dpi_max);
ratbag_resolution_set_dpi_list_from_range(res,
sensor->dpi_min,
sensor->dpi_max);
}
}

View File

@@ -393,9 +393,9 @@ logitech_g300_read_profile(struct ratbag_profile *profile)
resolution->is_default = res->is_default;
resolution->is_active = res->is_default;
ratbag_resolution_set_range(resolution,
LOGITECH_G300_DPI_MIN,
LOGITECH_G300_DPI_MAX);
ratbag_resolution_set_dpi_list_from_range(resolution,
LOGITECH_G300_DPI_MIN,
LOGITECH_G300_DPI_MAX);
}
ratbag_profile_for_each_button(profile, button)

View File

@@ -193,7 +193,9 @@ test_read_profile(struct ratbag_profile *profile)
assert(res);
ratbag_resolution_set_resolution(res, r->xres, r->yres, r->hz);
if (r0->dpi_min != 0 && r0->dpi_max != 0)
ratbag_resolution_set_range(res, r0->dpi_min, r0->dpi_max);
ratbag_resolution_set_dpi_list_from_range(res,
r0->dpi_min,
r0->dpi_max);
res->is_active = r->active;
if (r->active)
active_set = true;

View File

@@ -254,8 +254,10 @@ struct ratbag_resolution {
void *userdata;
struct list link;
unsigned index;
unsigned int dpi_max; /**< max resolution in dpi */
unsigned int dpi_min; /**< min resolution in dpi */
unsigned int dpis[300];
size_t ndpis;
unsigned int dpi_x; /**< x resolution in dpi */
unsigned int dpi_y; /**< y resolution in dpi */
unsigned int hz; /**< report rate in Hz */
@@ -473,10 +475,32 @@ ratbag_resolution_set_resolution(struct ratbag_resolution *res,
}
static inline void
ratbag_resolution_set_range(struct ratbag_resolution *res, int min, int max)
ratbag_resolution_set_dpi_list_from_range(struct ratbag_resolution *res,
unsigned int min, unsigned int max)
{
res->dpi_min = min;
res->dpi_max = max;
const unsigned int stepsize = 50;
bool maxed_out = false;
res->ndpis = 0;
/* FIXME: this should use an exponential approach, because who cares
* about 8200 vs 8250 dpi. */
while (res->ndpis < ARRAY_LENGTH(res->dpis)) {
unsigned int dpi = min + res->ndpis * stepsize;
if (dpi > (unsigned)max) {
maxed_out = true;
break;
}
res->dpis[res->ndpis] = dpi;
res->ndpis++;
}
if (!maxed_out)
log_bug_libratbag(res->profile->device->ratbag,
"%s: resolution range exceeds available space.\n",
res->profile->device->name);
}
static inline void

View File

@@ -1122,16 +1122,19 @@ ratbag_resolution_get_dpi(struct ratbag_resolution *resolution)
return resolution->dpi_x;
}
LIBRATBAG_EXPORT int
ratbag_resolution_get_dpi_maximum(struct ratbag_resolution *resolution)
LIBRATBAG_EXPORT size_t
ratbag_resolution_get_dpi_list(struct ratbag_resolution *resolution,
unsigned int *resolutions,
size_t nres)
{
return resolution->dpi_max;
}
_Static_assert(sizeof(*resolutions) == sizeof(*resolution->dpis), "type mismatch");
LIBRATBAG_EXPORT int
ratbag_resolution_get_dpi_minimum(struct ratbag_resolution *resolution)
{
return resolution->dpi_min;
assert(nres > 0);
memcpy(resolutions, resolution->dpis,
sizeof(unsigned int) * min(nres, resolution->ndpis));
return resolution->ndpis;
}
LIBRATBAG_EXPORT int

View File

@@ -843,28 +843,26 @@ ratbag_resolution_get_dpi(struct ratbag_resolution *resolution);
/**
* @ingroup resolution
*
* Get the maximum allowed resolution in DPI for the resolution mode.
* Get the number of resolutions in DPI available for this resolution.
* The list of DPI values is sorted in ascending order but may be filtered
* by libratbag and does not necessarily reflect all resolutions supported
* by the physical device.
*
* @param resolution A previously initialized ratbag resolution
* This function writes at most nres values but returns the number of
* DPI values available on this resolution. In other words, if it returns a
* number larger than nres, call it again with an array the size of the
* return value.
*
* @return The maximum resolution in dpi
* @retval 0 The maximum resolution is unknown to libratbag
* @param[out] resolutions Set to the supported DPI values in ascending order
* @param[in] nres The number of elements in resolutions
*
* @return The number of valid items in resolutions. If the returned value
* is larger than nres, the list was truncated.
*/
int
ratbag_resolution_get_dpi_maximum(struct ratbag_resolution *resolution);
/**
* @ingroup resolution
*
* Get the minimum allowed resolution in DPI for the resolution mode.
*
* @param resolution A previously initialized ratbag resolution
*
* @return The minimum resolution in dpi
* @retval 0 The minimum resolution is unknown to libratbag
*/
int
ratbag_resolution_get_dpi_minimum(struct ratbag_resolution *resolution);
size_t
ratbag_resolution_get_dpi_list(struct ratbag_resolution *resolution,
unsigned int *resolutions,
size_t nres);
/**
* @ingroup resolution