forked from drath/libratbag
Add per-resolution capabilities
Currently only the hooks for x/y resolution, the rest is unimplemented. Also the etekcity driver needs an update here. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
@@ -507,10 +507,12 @@ etekcity_read_profile(struct ratbag_profile *profile, unsigned int index)
|
||||
hz = report_rate;
|
||||
if (!(setting_report->dpi_mask & (1 << i))) {
|
||||
/* the profile is disabled, overwrite it */
|
||||
resolution->dpi = 0;
|
||||
resolution->dpi_x = 0;
|
||||
resolution->dpi_y = 0;
|
||||
resolution->hz = 0;
|
||||
}
|
||||
ratbag_resolution_init(profile, i, dpi,hz);
|
||||
/* FIXME */
|
||||
ratbag_resolution_init(profile, i, dpi, dpi, hz);
|
||||
resolution->is_active = (i == setting_report->current_dpi);
|
||||
}
|
||||
|
||||
@@ -622,7 +624,8 @@ etekcity_write_button(struct ratbag_button *button,
|
||||
}
|
||||
|
||||
static int
|
||||
etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
|
||||
etekcity_write_resolution_dpi(struct ratbag_resolution *resolution,
|
||||
int dpi_x, int dpi_y)
|
||||
{
|
||||
struct ratbag_profile *profile = resolution->profile;
|
||||
struct ratbag_device *device = profile->device;
|
||||
@@ -632,7 +635,9 @@ etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
|
||||
uint8_t *buf;
|
||||
int rc;
|
||||
|
||||
if (dpi < 50 || dpi > 8200 || dpi % 50)
|
||||
if (dpi_x < 50 || dpi_x > 8200 || dpi_x % 50)
|
||||
return -EINVAL;
|
||||
if (dpi_y < 50 || dpi_y > 8200 || dpi_y % 50)
|
||||
return -EINVAL;
|
||||
|
||||
settings_report = &drv_data->settings[profile->index];
|
||||
@@ -640,11 +645,10 @@ etekcity_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
|
||||
/* retrieve which resolution is asked to be changed */
|
||||
index = resolution - profile->resolution.modes;
|
||||
|
||||
/* FIXME: allow both x and y dpi to be set */
|
||||
settings_report->x_sensitivity = 0x0a;
|
||||
settings_report->y_sensitivity = 0x0a;
|
||||
settings_report->xres[index] = dpi / 50;
|
||||
settings_report->yres[index] = dpi / 50;
|
||||
settings_report->xres[index] = dpi_x / 50;
|
||||
settings_report->yres[index] = dpi_y / 50;
|
||||
|
||||
buf = (uint8_t*)settings_report;
|
||||
etekcity_set_config_profile(device, profile->index, ETEKCITY_CONFIG_SETTINGS);
|
||||
|
||||
@@ -139,10 +139,15 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index)
|
||||
|
||||
profile->resolution.num_modes = p.num_dpi_modes;
|
||||
for (i = 0; i < p.num_dpi_modes; i++) {
|
||||
/* FIXME: we should expose x/y res separately */
|
||||
ratbag_resolution_init(profile, i, p.dpi_modes[i].xres,
|
||||
ratbag_resolution_init(profile, i,
|
||||
p.dpi_modes[i].xres,
|
||||
p.dpi_modes[i].yres,
|
||||
p.refresh_rate);
|
||||
if (profile->is_active && profile->resolution.modes[i].dpi == xres)
|
||||
ratbag_resolution_set_cap(&profile->resolution.modes[i],
|
||||
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
|
||||
if (profile->is_active &&
|
||||
profile->resolution.modes[i].dpi_x == xres &&
|
||||
profile->resolution.modes[i].dpi_y == yres)
|
||||
profile->resolution.modes[i].is_active = true;
|
||||
if (i == p.default_dpi_mode)
|
||||
profile->resolution.modes[i].is_default = true;
|
||||
|
||||
@@ -208,8 +208,9 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
drv_data->num_sensors = MAX_RESOLUTIONS;
|
||||
profile->resolution.num_modes = drv_data->num_sensors;
|
||||
for (i = 0; i < profile->resolution.num_modes; i++) {
|
||||
int dpi = drv_data->sensors[i].dpi;
|
||||
/* FIXME: retrieve the refresh rate */
|
||||
ratbag_resolution_init(profile, i, drv_data->sensors[i].dpi, 0);
|
||||
ratbag_resolution_init(profile, i, dpi, dpi, 0);
|
||||
|
||||
/* FIXME: we mark all resolutions as active because
|
||||
* they are from different sensors */
|
||||
@@ -223,13 +224,15 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_write_resolution_dpi(struct ratbag_resolution *resolution, int dpi)
|
||||
hidpp20drv_write_resolution_dpi(struct ratbag_resolution *resolution,
|
||||
int dpi_x, int dpi_y)
|
||||
{
|
||||
struct ratbag_profile *profile = resolution->profile;
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct hidpp20_sensor *sensor;
|
||||
int rc, i;
|
||||
int dpi = dpi_x; /* dpi_x == dpi_y if we don't have the individual resolution cap */
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_SWITCHABLE_RESOLUTION_2201))
|
||||
return -ENOTSUP;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libratbag.h"
|
||||
#include "libratbag-util.h"
|
||||
@@ -167,7 +168,8 @@ struct ratbag_driver {
|
||||
*
|
||||
* Mandatory if the driver exports RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION.
|
||||
*/
|
||||
int (*write_resolution_dpi)(struct ratbag_resolution *resolution, int dpi);
|
||||
int (*write_resolution_dpi)(struct ratbag_resolution *resolution,
|
||||
int dpi_x, int dpi_y);
|
||||
|
||||
/* private */
|
||||
struct list link;
|
||||
@@ -178,10 +180,12 @@ struct ratbag_resolution{
|
||||
struct ratbag_profile *profile;
|
||||
int refcount;
|
||||
void *userdata;
|
||||
unsigned int dpi; /**< resolution on dpi */
|
||||
unsigned int dpi_x; /**< x resolution in dpi */
|
||||
unsigned int dpi_y; /**< y resolution in dpi */
|
||||
unsigned int hz; /**< report rate in Hz */
|
||||
bool is_active;
|
||||
bool is_default;
|
||||
uint32_t capabilities;
|
||||
};
|
||||
|
||||
struct ratbag_profile {
|
||||
@@ -309,15 +313,27 @@ ratbag_button_action_match(const struct ratbag_button_action *action,
|
||||
}
|
||||
|
||||
static inline void
|
||||
ratbag_resolution_init(struct ratbag_profile *profile, int index, int dpi, int hz)
|
||||
ratbag_resolution_init(struct ratbag_profile *profile, int index,
|
||||
int dpi_x, int dpi_y, int hz)
|
||||
{
|
||||
struct ratbag_resolution *res = &profile->resolution.modes[index];
|
||||
|
||||
res->profile = profile;
|
||||
res->dpi = dpi;
|
||||
res->dpi_x = dpi_x;
|
||||
res->dpi_y = dpi_y;
|
||||
res->hz = hz;
|
||||
res->is_active = false;
|
||||
res->is_default = false;
|
||||
res->capabilities = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ratbag_resolution_set_cap(struct ratbag_resolution *res,
|
||||
enum ratbag_resolution_capability cap)
|
||||
{
|
||||
assert(cap <= RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
|
||||
|
||||
res->capabilities = (1 << cap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -569,7 +569,7 @@ ratbag_create_profile(struct ratbag_device *device,
|
||||
list_init(&profile->buttons);
|
||||
|
||||
for (i = 0; i < MAX_RESOLUTIONS; i++)
|
||||
ratbag_resolution_init(profile, i, 0, 0);
|
||||
ratbag_resolution_init(profile, i, 0, 0, 0);
|
||||
profile->resolution.num_modes = 1;
|
||||
|
||||
assert(device->driver->read_profile);
|
||||
@@ -755,15 +755,48 @@ ratbag_resolution_unref(struct ratbag_resolution *resolution)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
|
||||
enum ratbag_resolution_capability cap)
|
||||
{
|
||||
switch (cap) {
|
||||
case RATBAG_RESOLUTION_CAP_INDIVIDUAL_REPORT_RATE:
|
||||
case RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return !!(resolution->capabilities & (1 << cap));
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
|
||||
unsigned int dpi)
|
||||
{
|
||||
struct ratbag_profile *profile = resolution->profile;
|
||||
resolution->dpi = dpi;
|
||||
resolution->dpi_x = dpi;
|
||||
resolution->dpi_y = dpi;
|
||||
|
||||
assert(profile->device->driver->write_resolution_dpi);
|
||||
return profile->device->driver->write_resolution_dpi(resolution, dpi);
|
||||
return profile->device->driver->write_resolution_dpi(resolution, dpi, dpi);
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution,
|
||||
unsigned int x, unsigned int y)
|
||||
{
|
||||
struct ratbag_profile *profile = resolution->profile;
|
||||
|
||||
if (!ratbag_resolution_has_capability(resolution,
|
||||
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION))
|
||||
return -1;
|
||||
|
||||
if ((x == 0 && y != 0) || (x != 0 && y == 0))
|
||||
return -1;
|
||||
|
||||
assert(profile->device->driver->write_resolution_dpi);
|
||||
return profile->device->driver->write_resolution_dpi(resolution, x, y);
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
@@ -778,7 +811,19 @@ ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_resolution_get_dpi(struct ratbag_resolution *resolution)
|
||||
{
|
||||
return resolution->dpi;
|
||||
return resolution->dpi_x;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_resolution_get_dpi_x(struct ratbag_resolution *resolution)
|
||||
{
|
||||
return resolution->dpi_x;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_resolution_get_dpi_y(struct ratbag_resolution *resolution)
|
||||
{
|
||||
return resolution->dpi_y;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
|
||||
@@ -552,10 +552,38 @@ ratbag_resolution_set_user_data(struct ratbag_resolution *resolution, void *user
|
||||
void*
|
||||
ratbag_resolution_get_user_data(const struct ratbag_resolution *resolution);
|
||||
|
||||
enum ratbag_resolution_capability {
|
||||
/**
|
||||
* The report rate can be set per resolution mode. If this property
|
||||
* is not available, all resolutions within the same profile have
|
||||
* the same report rate and changing one changes the others.
|
||||
*/
|
||||
RATBAG_RESOLUTION_CAP_INDIVIDUAL_REPORT_RATE = 1,
|
||||
|
||||
/**
|
||||
* The resolution can be set for x and y separately.
|
||||
*/
|
||||
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Check if a resolution has a specific capability.
|
||||
*
|
||||
* @return non-zero if the capability is available, zero otherwise.
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
|
||||
enum ratbag_resolution_capability cap);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Set the resolution in DPI for the resolution mode.
|
||||
* If the resolution has the @ref
|
||||
* RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability, this function
|
||||
* sets both x and y resolution to the given value.
|
||||
*
|
||||
* A value of 0 for dpi disables the mode.
|
||||
*
|
||||
@@ -570,20 +598,84 @@ ratbag_resolution_get_user_data(const struct ratbag_resolution *resolution);
|
||||
int
|
||||
ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
|
||||
unsigned int dpi);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Set the x and y resolution in DPI for the resolution mode.
|
||||
* If the resolution does not have the @ref
|
||||
* RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability, this function
|
||||
* returns an error and does nothing.
|
||||
*
|
||||
* A value of 0 for both x and y disables the mode. If either value is 0 and
|
||||
* the other value is non-zero, this function returns an error and does
|
||||
* nothing.
|
||||
*
|
||||
* If the resolution mode is the currently active mode and the profile is
|
||||
* the currently active profile, the change takes effect immediately.
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution with the
|
||||
* @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability
|
||||
* @param x The x resolution in dpi
|
||||
* @param y The y resolution in dpi
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution,
|
||||
unsigned int x, unsigned int y);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Get the resolution in DPI for the resolution mode.
|
||||
* If the resolution has the @ref
|
||||
* RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability, this function
|
||||
* returns the x resolution, see ratbag_resolution_get_dpi_x().
|
||||
*
|
||||
* A value of 0 for dpi indicates the mode is disabled.
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return The resolution in dpi
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_get_dpi(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Get the x resolution in DPI for the resolution mode. If the resolution
|
||||
* does not have the @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION
|
||||
* capability, this function is identical to ratbag_resolution_get_dpi().
|
||||
*
|
||||
* A value of 0 for dpi indicates the mode is disabled.
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution with the
|
||||
* @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability
|
||||
*
|
||||
* @return The resolution in dpi
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_get_dpi_x(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Get the y resolution in DPI for the resolution mode. If the resolution
|
||||
* does not have the @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION
|
||||
* capability, this function is identical to ratbag_resolution_get_dpi().
|
||||
*
|
||||
* A value of 0 for dpi indicates the mode is disabled.
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution with the
|
||||
* @ref RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION capability
|
||||
*
|
||||
* @return The resolution in dpi
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_get_dpi_y(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
|
||||
@@ -40,14 +40,18 @@ global:
|
||||
ratbag_profile_set_active;
|
||||
ratbag_profile_unref;
|
||||
ratbag_resolution_get_dpi;
|
||||
ratbag_resolution_get_dpi_x;
|
||||
ratbag_resolution_get_dpi_y;
|
||||
ratbag_resolution_get_report_rate;
|
||||
ratbag_resolution_get_user_data;
|
||||
ratbag_resolution_has_capability;
|
||||
ratbag_resolution_is_active;
|
||||
ratbag_resolution_is_default;
|
||||
ratbag_resolution_ref;
|
||||
ratbag_resolution_set_active;
|
||||
ratbag_resolution_set_default;
|
||||
ratbag_resolution_set_dpi;
|
||||
ratbag_resolution_set_dpi_xy;
|
||||
ratbag_resolution_set_report_rate;
|
||||
ratbag_resolution_set_user_data;
|
||||
ratbag_resolution_unref;
|
||||
|
||||
@@ -332,6 +332,14 @@ ratbag_cmd_info(struct ratbag *ratbag, uint32_t flags, int argc, char **argv)
|
||||
rate = ratbag_resolution_get_report_rate(res);
|
||||
if (dpi == 0)
|
||||
printf(" %d: <disabled>\n", j);
|
||||
else if (ratbag_resolution_has_capability(res,
|
||||
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION))
|
||||
printf(" %d: %dx%ddpi @ %dHz%s%s\n", j,
|
||||
ratbag_resolution_get_dpi_x(res),
|
||||
ratbag_resolution_get_dpi_y(res),
|
||||
rate,
|
||||
ratbag_resolution_is_active(res) ? " (active)" : "",
|
||||
ratbag_resolution_is_default(res) ? " (default)" : "");
|
||||
else
|
||||
printf(" %d: %ddpi @ %dHz%s%s\n", j, dpi, rate,
|
||||
ratbag_resolution_is_active(res) ? " (active)" : "",
|
||||
|
||||
Reference in New Issue
Block a user